1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
|
--- remove.c.orig 2003-05-05 15:15:48.000000000 +0200
+++ remove.c 2003-05-05 15:26:08.000000000 +0200
@@ -26,6 +26,12 @@
#include <sys/types.h>
#include <assert.h>
+/* SRM BEGIN */
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+/* SRM END */
+
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
@@ -81,6 +87,18 @@
int euidaccess ();
int yesno ();
+/* SRM BEGIN */
+#define BLOCKSIZE 32769
+#define DIR_SEPERATOR '/'
+#define FLUSH sync()
+#define RANDOM_DEVICE "/dev/urandom"
+static int secure = 0;
+static char fillbuf[BLOCKSIZE];
+static FILE *devrandom;
+/* Functions */
+static int secure_delete();
+/* SRM END */
+
extern char *program_name;
/* state initialized by remove_init, freed by remove_fini */
@@ -605,6 +623,103 @@
return status;
}
+/* SRM BEGIN */
+void fill_buf(char pattern[3]) {
+ int loop;
+ int where;
+ for (loop = 0; loop < (BLOCKSIZE / 3); loop++) {
+ where = loop * 3;
+ fillbuf[where] = pattern[0];
+ fillbuf[where+1] = pattern[1];
+ fillbuf[where+2] = pattern[2];
+ }
+}
+
+void random_buf() {
+ int loop;
+ if (devrandom != NULL)
+ for (loop = 0; loop < BLOCKSIZE; loop++)
+ fillbuf[loop] = (unsigned char) (256.0*rand()/(RAND_MAX+1.0));
+ else
+ fread(&fillbuf, BLOCKSIZE, 1, devrandom);
+}
+
+/* overwriting the file several times */
+ static int
+ secure_delete (delfile)
+ char *delfile;
+ {
+ unsigned char write_modes[27][3] = {
+ {"\x55\x55\x55"}, {"\xaa\xaa\xaa"}, {"\x92\x49\x24"}, {"\x49\x24\x92"},
+ {"\x24\x92\x49"}, {"\x00\x00\x00"}, {"\x11\x11\x11"}, {"\x22\x22\x22"},
+ {"\x33\x33\x33"}, {"\x44\x44\x44"}, {"\x55\x55\x55"}, {"\x66\x66\x66"},
+ {"\x77\x77\x77"}, {"\x88\x88\x88"}, {"\x99\x99\x99"}, {"\xaa\xaa\xaa"},
+ {"\xbb\xbb\xbb"}, {"\xcc\xcc\xcc"}, {"\xdd\xdd\xdd"}, {"\xee\xee\xee"},
+ {"\xff\xff\xff"}, {"\x92\x49\x24"}, {"\x49\x24\x92"}, {"\x24\x92\x49"},
+ {"\x6d\xb6\xdb"}, {"\xb6\xdb\x6d"}, {"\xdb\x6d\xb6"}
+ };
+ unsigned char std_array[3] = "\xff\xff\xff";
+ FILE *f;
+ int file;
+ unsigned long writes;
+ unsigned long counter;
+ unsigned long filesize;
+ struct stat filestat;
+ int turn;
+ int result;
+ unsigned char ch;
+ char newname[512];
+
+/* open the file, get the filesize, calculate the numbers of needed writings */
+ if (lstat(delfile, &filestat))
+ return 1;
+ if (! S_ISREG(filestat.st_mode))
+ return 1;
+ if ((f = fopen(delfile, "r+b")) == NULL)
+ return 1;
+ filesize = filestat.st_size;
+ writes = (1 + (filesize / BLOCKSIZE));
+ file=fileno(f);
+ (void) setvbuf(stdout, NULL, _IONBF, 0);
+ devrandom = fopen(RANDOM_DEVICE, "r");
+
+ if (secure > 1) {
+ fill_buf(std_array);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ fflush(f);
+ fsync(file);
+ }
+
+/* do the overwriting stuff */
+ for (turn=0; turn<=36; turn++) {
+ rewind(f);
+ if ((secure < 3) && (turn > 0)) break;
+ if ((turn>=5) && (turn<=31)) {
+ fill_buf(write_modes[turn-5]);
+ for (counter=1; counter<=writes; counter++)
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ } else {
+ for (counter=1; counter<=writes; counter++) {
+ random_buf();
+ fwrite(&fillbuf, 1, BLOCKSIZE, f);
+ }
+ }
+ fflush(f);
+ if (fsync(file) < 0)
+ FLUSH;
+ }
+ (void) fclose(f);
+ (void) fclose(devrandom);
+/* Hard Flush -> Force cached data to be written to disk */
+ FLUSH;
+/* open + truncating the file, so an attacker doesn't know the diskblocks */
+ if ((file = open(delfile, O_WRONLY | O_TRUNC)) >= 0)
+ close(file);
+ return 0;
+}
+/* SRM END */
+
/* Query the user if appropriate, and if ok try to remove the
file or directory specified by FS. Return RM_OK if it is removed,
and RM_ERROR or RM_USER_DECLINED if not. */
@@ -646,9 +761,16 @@
return RM_USER_DECLINED;
}
- if (x->verbose)
- printf (_("removing %s\n"), quote (full_filename (pathname)));
+ if (x->verbose) {
+ if (secure)
+ printf (_("wiping %s\n"), quote (full_filename (pathname)));
+ else
+ printf (_("removing %s\n"), quote (full_filename (pathname)));
+ }
+ if (secure)
+ secure_delete(pathname);
+
if (unlink (pathname) && (errno != ENOENT || !x->ignore_missing_files))
{
error (0, errno, _("cannot unlink %s"), quote (full_filename (pathname)));
@@ -821,6 +943,8 @@
{
mode_t filetype_mode;
+ secure = x->secure;
+
if (user_specified_name)
{
/* CAUTION: this use of base_name works only because any
--- rm.c.orig 2003-05-05 14:58:35.000000000 +0200
+++ rm.c 2003-05-05 15:16:31.000000000 +0200
@@ -58,7 +58,7 @@
#define PROGRAM_NAME "rm"
#define AUTHORS \
- "Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering"
+ "Paul Rubin, David MacKenzie, Richard Stallman, Jim Meyering, and van Hauser"
void strip_trailing_slashes ();
@@ -71,6 +71,9 @@
{"force", no_argument, NULL, 'f'},
{"interactive", no_argument, NULL, 'i'},
{"recursive", no_argument, NULL, 'r'},
+/* SRM BEGIN */
+ {"secure", no_argument, NULL, 's'},
+/* SRM END */
{"verbose", no_argument, NULL, 'v'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
@@ -93,6 +96,7 @@
-f, --force ignore nonexistent files, never prompt\n\
-i, --interactive prompt before any removal\n\
-r, -R, --recursive remove the contents of directories recursively\n\
+ -s, --secure secure overwrite (-sss for full security)\n\
-v, --verbose explain what is being done\n\
--help display this help and exit\n\
--version output version information and exit\n\
@@ -105,10 +109,11 @@
\n\
Note that if you use rm to remove a file, it is usually possible to recover\n\
the contents of that file. If you want more assurance that the contents are\n\
-truly unrecoverable, consider using shred.\n\
+truly unrecoverable, use the -s option.\n\
"),
program_name, program_name);
puts (_("\nReport bugs to <bug-fileutils@gnu.org>."));
+ puts (_("\nWith secure_delete patch by van Hauser <vh@thc.org>"));
}
exit (status);
}
@@ -122,6 +127,7 @@
x->recursive = 0;
x->stdin_tty = isatty (STDIN_FILENO);
x->verbose = 0;
+ x->secure = 0;
}
int
@@ -140,7 +146,7 @@
rm_option_init (&x);
- while ((c = getopt_long (argc, argv, "dfirvR", long_opts, NULL)) != -1)
+ while ((c = getopt_long (argc, argv, "dfirsvR", long_opts, NULL)) != -1)
{
switch (c)
{
@@ -161,6 +167,11 @@
case 'R':
x.recursive = 1;
break;
+/* SRM BEGIN */
+ case 's':
+ x.secure++;
+ break;
+/* SRM END */
case 'v':
x.verbose = 1;
break;
--- remove.h.orig 2003-05-05 15:13:47.000000000 +0200
+++ remove.h 2003-05-05 15:14:13.000000000 +0200
@@ -18,6 +18,9 @@
Only works for the super-user. */
int unlink_dirs;
+ /* If nonzero, secure overwrites file contents */
+ int secure;
+
/* If nonzero, display the name of each file removed. */
int verbose;
};
|