crypt.c - sbase - suckless unix tools
HTML git clone git://git.suckless.org/sbase
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
crypt.c (3857B)
---
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 file = strchr(line, ' ');
53 if (file == NULL || (file[1] != ' ' && file[1] != '*')) {
54 (*formatsucks)++;
55 continue;
56 }
57 if (file - line != sz * 2) {
58 (*formatsucks)++; /* checksum length mismatch */
59 continue;
60 }
61 *file = '\0';
62 file += 2;
63 for (p = file; *p && *p != '\n' && *p != '\r'; p++); /* strip newline */
64 *p = '\0';
65 if ((fd = open(file, O_RDONLY)) < 0) {
66 weprintf("open %s:", file);
67 (*noread)++;
68 continue;
69 }
70 if (cryptsum(ops, fd, file, md)) {
71 (*noread)++;
72 continue;
73 }
74 r = mdcheckline(line, md, sz);
75 if (r == 1) {
76 printf("%s: OK\n", file);
77 } else if (r == 0) {
78 printf("%s: FAILED\n", file);
79 (*nonmatch)++;
80 } else {
81 (*formatsucks)++;
82 }
83 close(fd);
84 }
85 free(line);
86 }
87
88 int
89 cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
90 {
91 FILE *fp;
92 int formatsucks = 0, noread = 0, nonmatch = 0, ret = 0;
93
94 if (argc == 0) {
95 mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch);
96 } else {
97 for (; *argv; argc--, argv++) {
98 if ((*argv)[0] == '-' && !(*argv)[1]) {
99 fp = stdin;
100 } else if (!(fp = fopen(*argv, "r"))) {
101 weprintf("fopen %s:", *argv);
102 ret = 1;
103 continue;
104 }
105 mdchecklist(fp, ops, md, sz, &formatsucks, &noread, &nonmatch);
106 if (fp != stdin)
107 fclose(fp);
108 }
109 }
110
111 if (formatsucks) {
112 weprintf("%d improperly formatted line%s\n",
113 formatsucks, formatsucks > 1 ? "s" : "");
114 ret = 1;
115 }
116 if (noread) {
117 weprintf("%d listed file%s could not be read\n",
118 noread, noread > 1 ? "s" : "");
119 ret = 1;
120 }
121 if (nonmatch) {
122 weprintf("%d computed checksum%s did NOT match\n",
123 nonmatch, nonmatch > 1 ? "s" : "");
124 ret = 1;
125 }
126
127 return ret;
128 }
129
130 int
131 cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz)
132 {
133 int fd;
134 int ret = 0;
135
136 if (argc == 0) {
137 if (cryptsum(ops, 0, "<stdin>", md))
138 ret = 1;
139 else
140 mdprint(md, "<stdin>", sz);
141 } else {
142 for (; *argv; argc--, argv++) {
143 if ((*argv)[0] == '-' && !(*argv)[1]) {
144 *argv = "<stdin>";
145 fd = 0;
146 } else if ((fd = open(*argv, O_RDONLY)) < 0) {
147 weprintf("open %s:", *argv);
148 ret = 1;
149 continue;
150 }
151 if (cryptsum(ops, fd, *argv, md))
152 ret = 1;
153 else
154 mdprint(md, *argv, sz);
155 if (fd != 0)
156 close(fd);
157 }
158 }
159
160 return ret;
161 }
162
163 int
164 cryptsum(struct crypt_ops *ops, int fd, const char *f, uint8_t *md)
165 {
166 uint8_t buf[BUFSIZ];
167 ssize_t n;
168
169 ops->init(ops->s);
170 while ((n = read(fd, buf, sizeof(buf))) > 0)
171 ops->update(ops->s, buf, n);
172 if (n < 0) {
173 weprintf("%s: read error:", f);
174 return 1;
175 }
176 ops->sum(ops->s, md);
177 return 0;
178 }
179
180 void
181 mdprint(const uint8_t *md, const char *f, size_t len)
182 {
183 size_t i;
184
185 for (i = 0; i < len; i++)
186 printf("%02x", md[i]);
187 printf(" %s\n", f);
188 }