/[winpt]/trunk/PTD/wptWipeFile.cpp
ViewVC logotype

Diff of /trunk/PTD/wptWipeFile.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 52 by werner, Fri Oct 28 12:57:05 2005 UTC revision 53 by twoaday, Wed Nov 2 09:01:29 2005 UTC
# Line 31  Line 31 
31  #endif  #endif
32    
33  #include <windows.h>  #include <windows.h>
 #include <windows.h>  
34  #include <stdio.h>  #include <stdio.h>
35  #include <stdlib.h>  #include <stdlib.h>
36  #include <sys/stat.h>  #include <sys/stat.h>
# Line 45  Line 44 
44  #include "wptTypes.h"  #include "wptTypes.h"
45  #include "wptCrypto.h"  #include "wptCrypto.h"
46    
47    #ifdef _MSC_VER
48  typedef unsigned __int64 DDWORD;  typedef unsigned __int64 DDWORD;
49    #else
50    typedef unsigned long long DDWORD;
51    #endif
52    
53  typedef struct {  typedef struct {
54      HANDLE fd;      HANDLE fd;
# Line 57  typedef struct { Line 60  typedef struct {
60      int    n_passes;      int    n_passes;
61  } wipe_context_s;  } wipe_context_s;
62    
63    struct arcfour_s {
64        BYTE *seed;
65        int  pos;
66        BYTE sbox[256];
67        DWORD i;
68        DWORD j;
69    };
70    
71    
72  void (*progress_cb) (void *, DDWORD, DDWORD);  void (*progress_cb) (void *, DDWORD, DDWORD);
73  static void *progress_cb_value = NULL;  static void *progress_cb_value = NULL;
# Line 64  static void *progress_cb_value = NULL; Line 75  static void *progress_cb_value = NULL;
75  void (*unlink_cb)(void *, const char *, int, int, int) = NULL;  void (*unlink_cb)(void *, const char *, int, int, int) = NULL;
76  static void *unlink_cb_value = NULL;  static void *unlink_cb_value = NULL;
77    
78    static int init_done = 0;
79    static struct arcfour_s rnd;
80    
81    
82    /* Add the random from buffer @buf with the length @buf_len
83       into the seed @seed. The seed length (256) used to
84       emulate a circular movment. */
85    static void
86    add_random (unsigned char *seed, int *seed_pos,
87                unsigned char *buf, int buf_len)
88    {
89        int i, s_pos = *seed_pos;
90    
91        for (i=0; i < buf_len; i++)
92            seed[(s_pos++ % 256)] ^= buf[i];
93        *seed_pos = s_pos % 256;
94    }
95    
96    
97    /* Enumerate all child windows. Store their text, their thread ID,
98       their placement and their dimension. */
99    static BOOL CALLBACK
100    child_proc (HWND h, LPARAM l)
101    {
102        struct arcfour_s *cb =  (struct arcfour_s*)l;
103        DWORD a = (DWORD)h;
104        WINDOWPLACEMENT p;
105        RECT r;
106        char buf[256];
107        int n;
108    
109        n  = GetWindowText (h, buf, 255);
110        if (n > 0)
111            add_random (cb->seed, &cb->pos, (BYTE*)buf, n);
112        add_random (cb->seed, &cb->pos, (BYTE*)&a, 4);
113        a = GetWindowThreadProcessId (h, NULL);
114        add_random (cb->seed, &cb->pos, (BYTE*)&a, 4);
115        GetWindowPlacement (h, &p);
116        add_random (cb->seed, &cb->pos, (BYTE*)&p, sizeof (p));
117        GetWindowRect (h, &r);
118        add_random (cb->seed, &cb->pos, (BYTE*)&r, sizeof (r));
119        return TRUE;
120    }
121    
122    
123    /* Initialize the seed with all kind of system variables. */
124    static void
125    init_random (unsigned char *seed)
126    {
127        int pos=0;
128        DWORD buf[16];
129        int i=0;
130    
131        buf[i++] = (DWORD)GetActiveWindow ();
132        buf[i++] = (DWORD)GetCapture ();
133        buf[i++] = (DWORD)GetClipboardOwner ();
134        buf[i++] = (DWORD)GetClipboardViewer ();
135        buf[i++] = (DWORD)GetCurrentProcess ();      
136        buf[i++] = (DWORD)GetCurrentProcessId ();
137        buf[i++] = (DWORD)GetCurrentThread ();
138        buf[i++] = (DWORD)GetDesktopWindow ();
139        buf[i++] = (DWORD)GetFocus ();
140        buf[i++] = (DWORD)GetMessagePos ();
141        buf[i++] = (DWORD)GetOpenClipboardWindow ();
142        buf[i++] = (DWORD)GetProcessHeap ();
143        buf[i++] = (DWORD)GetProcessWindowStation ();
144        buf[i++] = (DWORD)GetQueueStatus (QS_ALLEVENTS);
145        buf[i] = (DWORD)GetTickCount ();
146        add_random (seed, &pos, (BYTE*)buf, 4*i);
147    
148        {
149            POINT p;
150            GetCursorPos (&p);
151            add_random (seed, &pos, (BYTE*)&p, sizeof (p));
152            GetCaretPos (&p);
153            add_random (seed, &pos, (BYTE*)&p, sizeof (p));
154        }
155    
156        {
157            STARTUPINFO inf;
158            inf.cb = sizeof (inf);
159            GetStartupInfo (&inf);
160            add_random (seed, &pos, (BYTE*)&inf, sizeof (inf));
161        }
162    
163        {
164            MEMORYSTATUS st;
165            
166            st.dwLength = sizeof (st);
167            GlobalMemoryStatus (&st);
168            add_random (seed, &pos, (BYTE*)&st, sizeof (st));
169        }
170    
171        {
172            LARGE_INTEGER in;
173    
174            QueryPerformanceFrequency (&in);
175            add_random (seed, &pos, (BYTE*)&in, sizeof (in));
176            QueryPerformanceCounter (&in);
177            add_random (seed, &pos, (BYTE*)&in, sizeof (in));
178        }
179        {
180            rnd.seed = seed;
181            rnd.pos = pos;
182            EnumChildWindows (GetDesktopWindow (), child_proc, (LPARAM)&rnd);
183        }
184    
185    }
186    
187    
188    /* Initialize cipher with the seed as the key. */
189    static void
190    init_arcfour (struct arcfour_s *ctx, BYTE *key)
191    {
192        BYTE t;
193    
194        ctx->i = 0;
195        ctx->j = 0;
196        for (ctx->i=0; ctx->i < 256; ctx->i++)
197            ctx->sbox[ctx->i] = (BYTE)ctx->i;
198        for (ctx->i=0; ctx->i < 256; ctx->i++) {
199            ctx->j += (ctx->j+ctx->sbox[ctx->i]+key[ctx->i]);
200            ctx->j &= 255;
201            t = ctx->sbox[ctx->i];
202            ctx->sbox[ctx->i] = ctx->sbox[ctx->j];
203            ctx->sbox[ctx->j] = t;
204        }
205    }
206    
207    
208    /* Generate a single random byte. If the cipher is not
209       init, do an init first. */
210    static BYTE
211    rnd_byte (void)
212    {
213        struct arcfour_s *ctx = &rnd;
214        BYTE t;
215    
216        if (!init_done) {
217            BYTE buf[256];
218            init_random (buf);
219            init_arcfour (ctx, buf);
220            init_done = 1;
221        }
222    
223        ctx->i++; ctx->i &= 255;
224        ctx->j += ctx->sbox[ctx->i]; ctx->j &= 255;
225        t = ctx->sbox[ctx->i];
226        ctx->sbox[ctx->i] = ctx->sbox[ctx->j];
227        ctx->sbox[ctx->j] = t;
228        return ctx->sbox[(ctx->sbox[ctx->i] + ctx->sbox[ctx->j]) & 255];
229    }
230    
231    
232    /* Generate a single alpha-num charactor. */
233    static char
234    random_char (void)
235    {      
236        byte c = 0;
237    
238        while  (!isalnum(c))
239            c = rnd_byte ();
240        return c % 127;
241    }
242    
243    
244  /* Use the file handle in the context to overwrite a file  /* Use the file handle in the context to overwrite a file
245     with prepared buffer contents. */     with prepared buffer contents. */
246  static void  static void
# Line 98  overwrite (wipe_context_s *ctx) Line 275  overwrite (wipe_context_s *ctx)
275    
276  /* fill the buffer with random of the given level. */  /* fill the buffer with random of the given level. */
277  static void  static void
278  randomize_buffer (byte *buf, size_t bufsize, int level)  randomize_buffer (byte *buf, size_t bufsize)
279  {  {
280      const int blocksize = 512;      const int blocksize = 512;
281      int blocks = bufsize / blocksize;      int blocks = bufsize / blocksize;
282      int mod = bufsize % blocksize;      int mod = bufsize % blocksize;
283            int i;
284    
285      while (blocks--) {      while (blocks--) {
286          gpg_randomize (buf, blocksize, level);          for (i=0; i < blocksize; i++)
287                buf[i] = rnd_byte ();
288          buf += blocksize;          buf += blocksize;
289      }      }
290      if (mod)      for (i=0; i < mod; i++)
291          gpg_randomize (buf, mod, level);          buf[i] = rnd_byte ();
292  }  }
293    
294    
# Line 120  overwrite_random (int npasses, wipe_cont Line 299  overwrite_random (int npasses, wipe_cont
299      int i;      int i;
300            
301      for (i = 0; i < npasses; i++) {      for (i = 0; i < npasses; i++) {
302          randomize_buffer (ctx->buffer, ctx->buffsize, 0);          randomize_buffer (ctx->buffer, ctx->buffsize);
303          overwrite (ctx);          overwrite (ctx);
304      }      }
305  }  }
# Line 178  rename_unlink (const char *path) Line 357  rename_unlink (const char *path)
357          p = new_name;          p = new_name;
358      do {      do {
359          while (i < 14) {          while (i < 14) {
360              c = gpg_random_char (1);              c = random_char ();
361              *p = c;              *p = c;
362              p++;              p++;
363              i++;              i++;
# Line 202  leave: Line 381  leave:
381    
382    
383  /* return the filesize as an 64-bit integer. */  /* return the filesize as an 64-bit integer. */
384  static __int64  static DDWORD
385  GetFileSize64 (const char * path)  GetFileSize64 (const char * path)
386  {  {
387      FILE *fp = fopen (path, "r");      FILE *fp = fopen (path, "r");
# Line 249  _secure_unlink (const char * path, int m Line 428  _secure_unlink (const char * path, int m
428      else if (r_fd)      else if (r_fd)
429          *r_fd = ctx.fd;          *r_fd = ctx.fd;
430            
     gpg_quick_random_gen (1);  
431      if (unlink_cb)      if (unlink_cb)
432          unlink_cb (unlink_cb_value, ctx.name, 0, 0, 0);          unlink_cb (unlink_cb_value, ctx.name, 0, 0, 0);
433    
# Line 319  _secure_unlink (const char * path, int m Line 497  _secure_unlink (const char * path, int m
497  }  }
498    
499    
500  /* Delete a file in a secure way with the given mode. */  /* Delete a file in a secure way with the given mode @mode. */
501  extern "C" int  extern "C" int
502  secure_unlink (const char *path, int mode)  secure_unlink (const char *path, int mode)
503  {  {
504        /* If the file has one of the following attributes, the
505           chance the file really gets overwritten is very low so
506           we just to an unlink to spare time and entropy. */
507        DWORD attr = GetFileAttributes (path);
508        if ((attr & FILE_ATTRIBUTE_COMPRESSED) ||
509            (attr & FILE_ATTRIBUTE_ENCRYPTED) ||
510            (attr & FILE_ATTRIBUTE_SPARSE_FILE))
511            return DeleteFile (path); /* XXX */
512      return _secure_unlink (path, mode, NULL);      return _secure_unlink (path, mode, NULL);
513  }  }
514    

Legend:
Removed from v.52  
changed lines
  Added in v.53

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26