crypt.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
crypt.c (3700B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include <fcntl.h> | |
3 #include <stdint.h> | |
4 #include <stdio.h> | |
5 #include <stdlib.h> | |
6 #include <string.h> | |
7 #include <unistd.h> | |
8 | |
9 #include "../crypt.h" | |
10 #include "../text.h" | |
11 #include "../util.h" | |
12 | |
13 static int | |
14 hexdec(int c) | |
15 { | |
16 if (c >= '0' && c <= '9') | |
17 return c - '0'; | |
18 else if (c >= 'A' && c <= 'F') | |
19 return c - 'A' + 10; | |
20 else if (c >= 'a' && c <= 'f') | |
21 return c - 'a' + 10; | |
22 return -1; /* unknown character */ | |
23 } | |
24 | |
25 static int | |
26 mdcheckline(const char *s, uint8_t *md, size_t sz) | |
27 { | |
28 size_t i; | |
29 int b1, b2; | |
30 | |
31 for (i = 0; i < sz; i++) { | |
32 if (!*s || (b1 = hexdec(*s++)) < 0) | |
33 return -1; /* invalid format */ | |
34 if (!*s || (b2 = hexdec(*s++)) < 0) | |
35 return -1; /* invalid format */ | |
36 if ((uint8_t)((b1 << 4) | b2) != md[i]) | |
37 return 0; /* value mismatch */ | |
38 } | |
39 return (i == sz) ? 1 : 0; | |
40 } | |
41 | |
42 static void | |
43 mdchecklist(FILE *listfp, struct crypt_ops *ops, uint8_t *md, size_t sz, | |
44 int *formatsucks, int *noread, int *nonmatch) | |
45 { | |
46 int fd; | |
47 size_t bufsiz = 0; | |
48 int r; | |
49 char *line = NULL, *file, *p; | |
50 | |
51 while (getline(&line, &bufsiz, listfp) > 0) { | |
52 if (!(file = strstr(line, " "))) { | |
53 (*formatsucks)++; | |
54 continue; | |
55 } | |
56 if ((file - line) / 2 != sz) { | |
57 (*formatsucks)++; /* checksum length mismatch */ | |
58 continue; | |
59 } | |
60 *file = '\0'; | |
61 file += 2; | |
62 for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* … | |
63 *p = '\0'; | |
64 if ((fd = open(file, O_RDONLY)) < 0) { | |
65 weprintf("open %s:", file); | |
66 (*noread)++; | |
67 continue; | |
68 } | |
69 if (cryptsum(ops, fd, file, md)) { | |
70 (*noread)++; | |
71 continue; | |
72 } | |
73 r = mdcheckline(line, md, sz); | |
74 if (r == 1) { | |
75 printf("%s: OK\n", file); | |
76 } else if (r == 0) { | |
77 printf("%s: FAILED\n", file); | |
78 (*nonmatch)++; | |
79 } else { | |
80 (*formatsucks)++; | |
81 } | |
82 close(fd); | |
83 } | |
84 free(line); | |
85 } | |
86 | |
87 int | |
88 cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, s… | |
89 { | |
90 FILE *fp; | |
91 int formatsucks = 0, noread = 0, nonmatch = 0, ret = 0; | |
92 | |
93 if (argc == 0) { | |
94 mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &… | |
95 } else { | |
96 for (; *argv; argc--, argv++) { | |
97 if ((*argv)[0] == '-' && !(*argv)[1]) { | |
98 fp = stdin; | |
99 } else if (!(fp = fopen(*argv, "r"))) { | |
100 weprintf("fopen %s:", *argv); | |
101 ret = 1; | |
102 continue; | |
103 } | |
104 mdchecklist(fp, ops, md, sz, &formatsucks, &nore… | |
105 if (fp != stdin) | |
106 fclose(fp); | |
107 } | |
108 } | |
109 | |
110 if (formatsucks) { | |
111 weprintf("%d lines are improperly formatted\n", formatsu… | |
112 ret = 1; | |
113 } | |
114 if (noread) { | |
115 weprintf("%d listed file could not be read\n", noread); | |
116 ret = 1; | |
117 } | |
118 if (nonmatch) { | |
119 weprintf("%d computed checksums did NOT match\n", nonmat… | |
120 ret = 1; | |
121 } | |
122 | |
123 return ret; | |
124 } | |
125 | |
126 int | |
127 cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, si… | |
128 { | |
129 int fd; | |
130 int ret = 0; | |
131 | |
132 if (argc == 0) { | |
133 if (cryptsum(ops, 0, "<stdin>", md)) | |
134 ret = 1; | |
135 else | |
136 mdprint(md, "<stdin>", sz); | |
137 } else { | |
138 for (; *argv; argc--, argv++) { | |
139 if ((*argv)[0] == '-' && !(*argv)[1]) { | |
140 *argv = "<stdin>"; | |
141 fd = 0; | |
142 } else if ((fd = open(*argv, O_RDONLY)) < 0) { | |
143 weprintf("open %s:", *argv); | |
144 ret = 1; | |
145 continue; | |
146 } | |
147 if (cryptsum(ops, fd, *argv, md)) | |
148 ret = 1; | |
149 else | |
150 mdprint(md, *argv, sz); | |
151 if (fd != 0) | |
152 close(fd); | |
153 } | |
154 } | |
155 | |
156 return ret; | |
157 } | |
158 | |
159 int | |
160 cryptsum(struct crypt_ops *ops, int fd, const char *f, uint8_t *md) | |
161 { | |
162 uint8_t buf[BUFSIZ]; | |
163 ssize_t n; | |
164 | |
165 ops->init(ops->s); | |
166 while ((n = read(fd, buf, sizeof(buf))) > 0) | |
167 ops->update(ops->s, buf, n); | |
168 if (n < 0) { | |
169 weprintf("%s: read error:", f); | |
170 return 1; | |
171 } | |
172 ops->sum(ops->s, md); | |
173 return 0; | |
174 } | |
175 | |
176 void | |
177 mdprint(const uint8_t *md, const char *f, size_t len) | |
178 { | |
179 size_t i; | |
180 | |
181 for (i = 0; i < len; i++) | |
182 printf("%02x", md[i]); | |
183 printf(" %s\n", f); | |
184 } |