1 |
commit: 602608a0acadd589ec2ce85773aa5ec4ecfe228a |
2 |
Author: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Feb 28 16:11:02 2018 +0000 |
4 |
Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Feb 28 16:11:02 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/proj/prefix.git/commit/?id=602608a0 |
7 |
|
8 |
scripts/rsync-generation/hashgen: try to print verification issues prettier |
9 |
|
10 |
Still not very happy about this, need a clearer way to deal with issues |
11 |
to make a readable conclusion. |
12 |
|
13 |
scripts/rsync-generation/hashgen.c | 95 +++++++++++++++++++++++++++----------- |
14 |
1 file changed, 67 insertions(+), 28 deletions(-) |
15 |
|
16 |
diff --git a/scripts/rsync-generation/hashgen.c b/scripts/rsync-generation/hashgen.c |
17 |
index 5eb7b8640b..a4df7ca850 100644 |
18 |
--- a/scripts/rsync-generation/hashgen.c |
19 |
+++ b/scripts/rsync-generation/hashgen.c |
20 |
@@ -725,7 +725,7 @@ verify_gpg_sig(const char *path) |
21 |
} |
22 |
|
23 |
static char |
24 |
-verify_file(const char *dir, char *mfline) |
25 |
+verify_file(const char *dir, char *mfline, const char *mfest) |
26 |
{ |
27 |
char *path; |
28 |
char *size; |
29 |
@@ -741,14 +741,15 @@ verify_file(const char *dir, char *mfline) |
30 |
char blak2b[(BLAKE2B_OUTBYTES * 2) + 1]; |
31 |
char ret = 0; |
32 |
|
33 |
- /* mfline is a Manifest file line with type stripped, something like: |
34 |
- * path/to/file <SIZE> <HASHTYPE HASH ...> |
35 |
+ /* mfline is a Manifest file line with type and leading path |
36 |
+ * stripped, something like: |
37 |
+ * file <SIZE> <HASHTYPE HASH ...> |
38 |
* we parse this, and verify the size and hashes */ |
39 |
|
40 |
path = mfline; |
41 |
p = strchr(path, ' '); |
42 |
if (p == NULL) { |
43 |
- fprintf(stderr, "%s: corrupt manifest line: %s\n", dir, path); |
44 |
+ fprintf(stderr, "%s: corrupt manifest line: %s\n", mfest, path); |
45 |
return 1; |
46 |
} |
47 |
*p++ = '\0'; |
48 |
@@ -757,14 +758,14 @@ verify_file(const char *dir, char *mfline) |
49 |
p = strchr(size, ' '); |
50 |
if (p == NULL) { |
51 |
fprintf(stderr, "%s: corrupt manifest line, need size for %s\n", |
52 |
- dir, path); |
53 |
+ mfest, path); |
54 |
return 1; |
55 |
} |
56 |
*p++ = '\0'; |
57 |
fsize = strtoll(size, NULL, 10); |
58 |
if (fsize == 0 && errno == EINVAL) { |
59 |
fprintf(stderr, "%s: corrupt manifest line, size is not a number: %s\n", |
60 |
- dir, size); |
61 |
+ dir + 2, size); |
62 |
return 1; |
63 |
} |
64 |
|
65 |
@@ -773,13 +774,15 @@ verify_file(const char *dir, char *mfline) |
66 |
get_hashes(buf, sha256, sha512, whrlpl, blak2b, &flen); |
67 |
|
68 |
if (flen == 0) { |
69 |
- fprintf(stderr, "cannot locate %s\n", path); |
70 |
+ fprintf(stderr, "cannot locate %s/%s\n", dir + 2, path); |
71 |
return 1; |
72 |
} |
73 |
|
74 |
if (flen != fsize) { |
75 |
- fprintf(stderr, "%s: size mismatch, got: %zd, expected: %lld\n", |
76 |
- path, flen, fsize); |
77 |
+ printf("%s:%s:\n- file size mismatch\n" |
78 |
+ " got: %zd\n" |
79 |
+ " expected: %lld\n", |
80 |
+ mfest, path, flen, fsize); |
81 |
return 1; |
82 |
} |
83 |
|
84 |
@@ -790,7 +793,7 @@ verify_file(const char *dir, char *mfline) |
85 |
p = strchr(hashtype, ' '); |
86 |
if (p == NULL) { |
87 |
fprintf(stderr, "%s: corrupt manifest line, missing hash type\n", |
88 |
- path); |
89 |
+ mfest); |
90 |
return 1; |
91 |
} |
92 |
*p++ = '\0'; |
93 |
@@ -800,11 +803,14 @@ verify_file(const char *dir, char *mfline) |
94 |
if (p != NULL) |
95 |
*p++ = '\0'; |
96 |
|
97 |
+#define idif(X) if (X == 0) printf("%s:%s:\n", mfest, path); |
98 |
if (strcmp(hashtype, "SHA256") == 0) { |
99 |
if (!(hashes & HASH_SHA256)) { |
100 |
+ idif(ret); |
101 |
printf("- warning: hash SHA256 ignored as " |
102 |
"it is not enabled for this repository\n"); |
103 |
} else if (strcmp(hash, sha256) != 0) { |
104 |
+ idif(ret); |
105 |
printf("- SHA256 hash mismatch\n" |
106 |
" computed: '%s'\n" |
107 |
" recorded in manifest: '%s'\n", |
108 |
@@ -814,9 +820,11 @@ verify_file(const char *dir, char *mfline) |
109 |
sha256[0] = '\0'; |
110 |
} else if (strcmp(hashtype, "SHA512") == 0) { |
111 |
if (!(hashes & HASH_SHA512)) { |
112 |
+ idif(ret); |
113 |
printf("- warning: hash SHA512 ignored as " |
114 |
"it is not enabled for this repository\n"); |
115 |
} else if (strcmp(hash, sha512) != 0) { |
116 |
+ idif(ret); |
117 |
printf("- SHA512 hash mismatch\n" |
118 |
" computed: '%s'\n" |
119 |
" recorded in manifest: '%s'\n", |
120 |
@@ -826,9 +834,11 @@ verify_file(const char *dir, char *mfline) |
121 |
sha512[0] = '\0'; |
122 |
} else if (strcmp(hashtype, "WHIRLPOOL") == 0) { |
123 |
if (!(hashes & HASH_WHIRLPOOL)) { |
124 |
+ idif(ret); |
125 |
printf("- warning: hash WHIRLPOOL ignored as " |
126 |
"it is not enabled for this repository\n"); |
127 |
} else if (strcmp(hash, whrlpl) != 0) { |
128 |
+ idif(ret); |
129 |
printf("- WHIRLPOOL hash mismatch\n" |
130 |
" computed: '%s'\n" |
131 |
" recorded in manifest: '%s'\n", |
132 |
@@ -838,9 +848,11 @@ verify_file(const char *dir, char *mfline) |
133 |
whrlpl[0] = '\0'; |
134 |
} else if (strcmp(hashtype, "BLAKE2B") == 0) { |
135 |
if (!(hashes & HASH_BLAKE2B)) { |
136 |
+ idif(ret); |
137 |
printf("- warning: hash BLAKE2B ignored as " |
138 |
"it is not enabled for this repository\n"); |
139 |
} else if (strcmp(hash, blak2b) != 0) { |
140 |
+ idif(ret); |
141 |
printf("- BLAKE2B hash mismatch\n" |
142 |
" computed: '%s'\n" |
143 |
" recorded in manifest: '%s'\n", |
144 |
@@ -849,24 +861,29 @@ verify_file(const char *dir, char *mfline) |
145 |
} |
146 |
blak2b[0] = '\0'; |
147 |
} else { |
148 |
+ idif(ret); |
149 |
printf("- unsupported hash: %s\n", hashtype); |
150 |
ret = 1; |
151 |
} |
152 |
} |
153 |
|
154 |
if (sha256[0] != '\0') { |
155 |
+ idif(ret); |
156 |
printf("- missing hash: SHA256\n"); |
157 |
ret = 1; |
158 |
} |
159 |
if (sha512[0] != '\0') { |
160 |
+ idif(ret); |
161 |
printf("- missing hash: SHA512\n"); |
162 |
ret = 1; |
163 |
} |
164 |
if (whrlpl[0] != '\0') { |
165 |
+ idif(ret); |
166 |
printf("- missing hash: WHIRLPOOL\n"); |
167 |
ret = 1; |
168 |
} |
169 |
if (blak2b[0] != '\0') { |
170 |
+ idif(ret); |
171 |
printf("- missing hash: BLAKE2B\n"); |
172 |
ret = 1; |
173 |
} |
174 |
@@ -904,7 +921,12 @@ static char verify_manifest(const char *dir, const char *manifest); |
175 |
|
176 |
#define LISTSZ 64 |
177 |
static char |
178 |
-verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
179 |
+verify_dir( |
180 |
+ const char *dir, |
181 |
+ char **elems, |
182 |
+ size_t elemslen, |
183 |
+ size_t skippath, |
184 |
+ const char *mfest) |
185 |
{ |
186 |
DIR *d; |
187 |
struct dirent *e; |
188 |
@@ -924,7 +946,7 @@ verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
189 |
if (elemslen == 1 && skippath == 0 && |
190 |
**elems == 'M' && strchr(*elems + 2, '/') == NULL) |
191 |
{ |
192 |
- if ((ret = verify_file(dir, *elems + 2)) == 0) { |
193 |
+ if ((ret = verify_file(dir, *elems + 2, mfest)) == 0) { |
194 |
slash = strchr(*elems + 2, ' '); |
195 |
if (slash != NULL) |
196 |
*slash = '\0'; |
197 |
@@ -997,13 +1019,12 @@ verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
198 |
size_t skiplen = strlen(dir) + 1 + sublen; |
199 |
/* sub-Manifest, we need to do a proper recurse */ |
200 |
slash = strrchr(entry, '/'); /* cannot be NULL */ |
201 |
- snprintf(ndir, sizeof(ndir), |
202 |
- "%s/%s", dir, entry); |
203 |
+ snprintf(ndir, sizeof(ndir), "%s/%s", dir, entry); |
204 |
ndir[skiplen] = '\0'; |
205 |
slash = strchr(ndir + skiplen + 1, ' '); |
206 |
if (slash != NULL) /* path should fit in ndir ... */ |
207 |
*slash = '\0'; |
208 |
- if (verify_file(dir, entry) != 0 || |
209 |
+ if (verify_file(dir, entry, mfest) != 0 || |
210 |
verify_manifest(ndir, ndir + skiplen + 1) != 0) |
211 |
ret |= 1; |
212 |
} else { |
213 |
@@ -1019,7 +1040,7 @@ verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
214 |
snprintf(ndir, sizeof(ndir), "%s/%.*s", dir, |
215 |
(int)sublen, elems[elemstart] + 2 + skippath); |
216 |
ret |= verify_dir(ndir, subelems, |
217 |
- curelem - elemstart, skippath + sublen + 1); |
218 |
+ curelem - elemstart, skippath + sublen + 1, mfest); |
219 |
curelem--; /* move back, see below */ |
220 |
} |
221 |
|
222 |
@@ -1045,7 +1066,7 @@ verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
223 |
if (cmp == 0) { |
224 |
/* equal, so yay */ |
225 |
if (etpe == 'D') { |
226 |
- ret |= verify_file(dir, entry); |
227 |
+ ret |= verify_file(dir, entry, mfest); |
228 |
} |
229 |
/* else this is I(GNORE) or S(ubdir), which means it is |
230 |
* ok in any way (M shouldn't happen) */ |
231 |
@@ -1061,14 +1082,14 @@ verify_dir(const char *dir, char **elems, size_t elemslen, size_t skippath) |
232 |
if (slash != NULL) |
233 |
*slash = '\0'; |
234 |
fprintf(stderr, "%s: missing %s file: %s\n", |
235 |
- dir, etpe == 'M' ? "MANIFEST" : "DATA", entry); |
236 |
+ mfest, etpe == 'M' ? "MANIFEST" : "DATA", entry); |
237 |
} |
238 |
curelem++; |
239 |
} else if (cmp > 0) { |
240 |
/* dir has extra element */ |
241 |
ret |= 1; |
242 |
fprintf(stderr, "%s: stray file not in Manifest: %s\n", |
243 |
- dir, dentries[curdentry]); |
244 |
+ mfest, dentries[curdentry]); |
245 |
curdentry++; |
246 |
} |
247 |
} |
248 |
@@ -1085,6 +1106,7 @@ verify_manifest(const char *dir, const char *manifest) |
249 |
char buf[8192]; |
250 |
FILE *f; |
251 |
gzFile mf; |
252 |
+ char ret = 0; |
253 |
|
254 |
size_t elemssize = 0; |
255 |
size_t elemslen = 0; |
256 |
@@ -1181,10 +1203,11 @@ verify_manifest(const char *dir, const char *manifest) |
257 |
* the larger Manifest.files.gz |
258 |
*/ |
259 |
qsort(elems, elemslen, sizeof(elems[0]), compare_elems); |
260 |
- verify_dir(dir, elems, elemslen, 0); |
261 |
+ snprintf(buf, sizeof(buf), "%s/%s", dir, manifest); |
262 |
+ ret = verify_dir(dir, elems, elemslen, 0, buf + 2); |
263 |
free(elems); |
264 |
|
265 |
- return 0; |
266 |
+ return ret; |
267 |
} |
268 |
|
269 |
static char * |
270 |
@@ -1194,6 +1217,7 @@ process_dir_vrfy(const char *dir) |
271 |
char buf[8192]; |
272 |
int newhashes; |
273 |
|
274 |
+ fprintf(stdout, "verifying %s...\n", dir); |
275 |
snprintf(buf, sizeof(buf), "%s/metadata/layout.conf", dir); |
276 |
if ((newhashes = parse_layout_conf(buf)) != 0) { |
277 |
hashes = newhashes; |
278 |
@@ -1202,8 +1226,12 @@ process_dir_vrfy(const char *dir) |
279 |
return "not on full tree"; |
280 |
} |
281 |
|
282 |
- snprintf(buf, sizeof(buf), "%s/%s", dir, str_manifest); |
283 |
- if (verify_gpg_sig(buf) != 0) |
284 |
+ if (chdir(dir) != 0) { |
285 |
+ fprintf(stderr, "cannot chdir() to %s: %s\n", dir, strerror(errno)); |
286 |
+ return "not a directory"; |
287 |
+ } |
288 |
+ |
289 |
+ if (verify_gpg_sig(str_manifest) != 0) |
290 |
ret = "gpg signature invalid"; |
291 |
|
292 |
/* verification goes like this: |
293 |
@@ -1214,7 +1242,7 @@ process_dir_vrfy(const char *dir) |
294 |
* be there |
295 |
* - recurse into directories for which Manifest files are defined */ |
296 |
|
297 |
- if (verify_manifest(dir, str_manifest) != 0) |
298 |
+ if (verify_manifest(".\0", str_manifest) != 0) |
299 |
ret = "manifest verification failed"; |
300 |
|
301 |
return ret; |
302 |
@@ -1226,6 +1254,8 @@ main(int argc, char *argv[]) |
303 |
char *prog; |
304 |
char *(*runfunc)(const char *); |
305 |
int arg = 1; |
306 |
+ int ret = 0; |
307 |
+ char *rsn; |
308 |
|
309 |
if ((prog = strrchr(argv[0], '/')) == NULL) |
310 |
prog = argv[0]; |
311 |
@@ -1249,11 +1279,20 @@ main(int argc, char *argv[]) |
312 |
gpgme_check_version(NULL); |
313 |
|
314 |
if (argc > 1) { |
315 |
- for (; arg < argc; arg++) |
316 |
- runfunc(argv[arg]); |
317 |
+ for (; arg < argc; arg++) { |
318 |
+ rsn = runfunc(argv[arg]); |
319 |
+ if (rsn != NULL) { |
320 |
+ printf("%s\n", rsn); |
321 |
+ ret |= 1; |
322 |
+ } |
323 |
+ } |
324 |
} else { |
325 |
- runfunc("."); |
326 |
+ rsn = runfunc("."); |
327 |
+ if (rsn != NULL) { |
328 |
+ printf("%s\n", rsn); |
329 |
+ ret |= 1; |
330 |
+ } |
331 |
} |
332 |
|
333 |
- return 0; |
334 |
+ return ret; |
335 |
} |