]>
Commit | Line | Data |
---|---|---|
cc0d019f | 1 | /* |
b19ccc9e | 2 | * "$Id: removefile.c 7720 2008-07-11 22:46:21Z mike $" |
cc0d019f MS |
3 | * |
4 | * "Secure" file removal function for the Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 2007 by Apple Inc. | |
7 | * Copyright 1997-2007 by Easy Software Products, all rights reserved. | |
8 | * | |
9 | * These coded instructions, statements, and computer programs are the | |
10 | * property of Apple Inc. and are protected by Federal copyright | |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * "LICENSE" which should have been included with this file. If this | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
14 | * | |
15 | * Contents: | |
16 | * | |
17 | * cupsdRemoveFile() - Remove a file using the 7-pass US DoD method. | |
18 | * overwrite_data() - Overwrite the data in a file. | |
19 | */ | |
20 | ||
21 | /* | |
22 | * Include necessary headers... | |
23 | */ | |
24 | ||
25 | #include "cupsd.h" | |
26 | #ifdef HAVE_REMOVEFILE | |
27 | # include <removefile.h> | |
28 | #else | |
29 | static int overwrite_data(int fd, const char *buffer, int bufsize, | |
30 | int filesize); | |
31 | #endif /* HAVE_REMOVEFILE */ | |
32 | ||
33 | ||
34 | /* | |
35 | * 'cupsdRemoveFile()' - Remove a file using the 7-pass US DoD method. | |
36 | */ | |
37 | ||
38 | int /* O - 0 on success, -1 on error */ | |
39 | cupsdRemoveFile(const char *filename) /* I - File to remove */ | |
40 | { | |
41 | #ifdef HAVE_REMOVEFILE | |
42 | int ret; /* Return value */ | |
43 | removefile_state_t s; /* Remove state variable */ | |
44 | ||
45 | ||
46 | s = removefile_state_alloc(); | |
47 | ret = removefile(filename, s, REMOVEFILE_SECURE_7_PASS); | |
48 | ||
49 | removefile_state_free(s); | |
50 | ||
51 | return (ret); | |
52 | ||
53 | #else | |
54 | int fd; /* File descriptor */ | |
55 | struct stat info; /* File information */ | |
56 | char buffer[512]; /* Data buffer */ | |
57 | int i; /* Looping var */ | |
58 | ||
59 | ||
60 | /* | |
61 | * First open the file for writing in exclusive mode. | |
62 | */ | |
63 | ||
64 | if ((fd = open(filename, O_WRONLY | O_EXCL)) < 0) | |
65 | return (-1); | |
66 | ||
67 | /* | |
68 | * Delete the file now - it will still be around as long as the file is | |
69 | * open... | |
70 | */ | |
71 | ||
72 | unlink(filename); | |
73 | ||
74 | /* | |
75 | * Then get the file size... | |
76 | */ | |
77 | ||
78 | if (fstat(fd, &info)) | |
79 | { | |
80 | close(fd); | |
81 | return (-1); | |
82 | } | |
83 | ||
84 | /* | |
85 | * Overwrite the file 7 times with 0xF6, 0x00, 0xFF, random, 0x00, 0xFF, | |
86 | * and more random data. | |
87 | */ | |
88 | ||
89 | memset(buffer, 0xF6, sizeof(buffer)); | |
90 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
91 | { | |
92 | close(fd); | |
93 | return (-1); | |
94 | } | |
95 | ||
96 | memset(buffer, 0x00, sizeof(buffer)); | |
97 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
98 | { | |
99 | close(fd); | |
100 | return (-1); | |
101 | } | |
102 | ||
103 | memset(buffer, 0xFF, sizeof(buffer)); | |
104 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
105 | { | |
106 | close(fd); | |
107 | return (-1); | |
108 | } | |
109 | ||
110 | for (i = 0; i < sizeof(buffer); i ++) | |
111 | buffer[i] = rand(); | |
112 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
113 | { | |
114 | close(fd); | |
115 | return (-1); | |
116 | } | |
117 | ||
118 | memset(buffer, 0x00, sizeof(buffer)); | |
119 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
120 | { | |
121 | close(fd); | |
122 | return (-1); | |
123 | } | |
124 | ||
125 | memset(buffer, 0xFF, sizeof(buffer)); | |
126 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
127 | { | |
128 | close(fd); | |
129 | return (-1); | |
130 | } | |
131 | ||
132 | for (i = 0; i < sizeof(buffer); i ++) | |
133 | buffer[i] = rand(); | |
134 | if (overwrite_data(fd, buffer, sizeof(buffer), (int)info.st_size)) | |
135 | { | |
136 | close(fd); | |
137 | return (-1); | |
138 | } | |
139 | ||
140 | /* | |
141 | * Whew! Close the file (which will lead to the actual deletion) and | |
142 | * return success... | |
143 | */ | |
144 | ||
145 | close(fd); | |
146 | return (0); | |
147 | #endif /* HAVE_REMOVEFILE */ | |
148 | } | |
149 | ||
150 | ||
151 | #ifndef HAVE_REMOVEFILE | |
152 | /* | |
153 | * 'overwrite_data()' - Overwrite the data in a file. | |
154 | */ | |
155 | ||
156 | static int /* O - 0 on success, -1 on error */ | |
157 | overwrite_data(int fd, /* I - File descriptor */ | |
158 | const char *buffer, /* I - Buffer to write */ | |
159 | int bufsize, /* I - Size of buffer */ | |
160 | int filesize) /* I - Size of file */ | |
161 | { | |
162 | int bytes; /* Bytes to write/written */ | |
163 | ||
164 | ||
165 | /* | |
166 | * Start at the beginning of the file... | |
167 | */ | |
168 | ||
169 | if (lseek(fd, 0, SEEK_SET) < 0) | |
170 | return (-1); | |
171 | ||
172 | /* | |
173 | * Fill the file with the provided data... | |
174 | */ | |
175 | ||
176 | while (filesize > 0) | |
177 | { | |
178 | if (filesize > bufsize) | |
179 | bytes = bufsize; | |
180 | else | |
181 | bytes = filesize; | |
182 | ||
183 | if ((bytes = write(fd, buffer, bytes)) < 0) | |
184 | return (-1); | |
185 | ||
186 | filesize -= bytes; | |
187 | } | |
188 | ||
189 | /* | |
190 | * Force the changes to disk... | |
191 | */ | |
192 | ||
193 | return (fsync(fd)); | |
194 | } | |
195 | #endif /* HAVE_REMOVEFILE */ | |
196 | ||
197 | ||
198 | #ifdef TEST | |
1f0275e3 | 199 | # define testmain main |
cc0d019f | 200 | int |
1f0275e3 | 201 | testmain(void) |
cc0d019f MS |
202 | { |
203 | FILE *fp; | |
204 | ||
205 | ||
206 | fp = fopen("testfile.secure", "w"); | |
207 | fputs("Hello, World!\n", fp); | |
208 | fputs("Now is the time for all good men to come to the aid of their " | |
209 | "country.\n", fp); | |
210 | fclose(fp); | |
211 | ||
212 | if (cupsdRemoveFile("testfile.secure")) | |
213 | { | |
214 | printf("cupsdRemoveFile: FAIL (%s)\n", strerror(errno)); | |
215 | return (1); | |
216 | } | |
217 | else | |
218 | { | |
219 | puts("cupsdRemoveFile: PASS"); | |
220 | return (0); | |
221 | } | |
222 | } | |
223 | #endif /* TEST */ | |
224 | ||
225 | ||
226 | /* | |
b19ccc9e | 227 | * End of "$Id: removefile.c 7720 2008-07-11 22:46:21Z mike $". |
cc0d019f | 228 | */ |