Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in net-misc/openssh-blacklist/files: blacklist-encode.c
Date: Sat, 31 May 2008 09:47:57
Message-Id: E1K2Ngm-0001Yr-6T@stork.gentoo.org
1 vapier 08/05/31 09:47:52
2
3 Added: blacklist-encode.c
4 Log:
5 Initial import #221759.
6 (Portage version: 2.2_pre5.spank.spunk)
7
8 Revision Changes Path
9 1.1 net-misc/openssh-blacklist/files/blacklist-encode.c
10
11 file : http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/openssh-blacklist/files/blacklist-encode.c?rev=1.1&view=markup
12 plain: http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/openssh-blacklist/files/blacklist-encode.c?rev=1.1&content-type=text/plain
13
14 Index: blacklist-encode.c
15 ===================================================================
16 /*
17 * The blacklist encoder for RSA/DSA key blacklisting based on partial
18 * fingerprints,
19 * developed under Openwall Project for Owl - http://www.openwall.com/Owl/
20 *
21 * Copyright (c) 2008 Dmitry V. Levin <ldv at cvs.openwall.com>
22 *
23 * Permission to use, copy, modify, and distribute this software for any
24 * purpose with or without fee is hereby granted, provided that the above
25 * copyright notice and this permission notice appear in all copies.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
28 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
30 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
31 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
32 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
33 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
34 *
35 * The blacklist encoding was designed by Solar Designer and Dmitry V. Levin.
36 * No intellectual property rights to the encoding scheme are claimed.
37 *
38 * This effort was supported by CivicActions - http://www.civicactions.com
39 *
40 * The file size to encode 294,903 of 48-bit fingerprints is just 1.3 MB,
41 * which corresponds to less than 4.5 bytes per fingerprint.
42 */
43
44 #ifndef _GNU_SOURCE
45 # define _GNU_SOURCE
46 #endif
47
48 #include <string.h>
49 #include <stdlib.h>
50 #include <stdint.h>
51 #include <stdio.h>
52 #include <errno.h>
53 #include <error.h>
54 #include <limits.h>
55
56 static void *
57 xmalloc(size_t size)
58 {
59 void *r = malloc(size);
60
61 if (!r)
62 error(EXIT_FAILURE, errno, "malloc: allocating %lu bytes",
63 (unsigned long) size);
64 return r;
65 }
66
67 static void *
68 xcalloc(size_t nmemb, size_t size)
69 {
70 void *r = calloc(nmemb, size);
71
72 if (!r)
73 error(EXIT_FAILURE, errno, "calloc: allocating %lu*%lu bytes",
74 (unsigned long) nmemb, (unsigned long) size);
75 return r;
76 }
77
78 static void *
79 xrealloc(void *ptr, size_t nmemb, size_t elem_size)
80 {
81 if (nmemb && ULONG_MAX / nmemb < elem_size)
82 error(EXIT_FAILURE, 0, "realloc: nmemb*size > ULONG_MAX");
83
84 size_t size = nmemb * elem_size;
85 void *r = realloc(ptr, size);
86
87 if (!r)
88 error(EXIT_FAILURE, errno,
89 "realloc: allocating %lu*%lu bytes",
90 (unsigned long) nmemb, (unsigned long) elem_size);
91 return r;
92 }
93
94 static char *
95 xstrdup(const char *s)
96 {
97 size_t len = strlen(s);
98 char *r = xmalloc(len + 1);
99
100 memcpy(r, s, len + 1);
101 return r;
102 }
103
104 static unsigned
105 c2u(uint8_t c)
106 {
107 return (c >= 'a') ? (c - 'a' + 10) : (c - '0');
108 }
109
110 static char **records = NULL;
111 static unsigned records_count = 0;
112
113 static int
114 comparator(const void *p1, const void *p2)
115 {
116 return strcmp(*(char *const *) p1, *(char *const *) p2);
117 }
118
119 static void
120 read_stream(FILE *fp, unsigned bytes)
121 {
122 char *line = NULL;
123 unsigned size = 0, allocated = 0, len = bytes * 2;
124 int n;
125
126 while ((n = getline(&line, &size, fp)) >= 0)
127 {
128 if (n > 0 && line[n - 1] == '\n')
129 line[--n] = '\0';
130 if (n < len || strspn(line, "0123456789abcdef") < n)
131 continue; /* ignore short or invalid lines */
132 line[len] = '\0';
133
134 if (!records)
135 records = xcalloc(allocated = 1024, sizeof(*records));
136 if (records_count >= allocated)
137 records = xrealloc(records, allocated *= 2,
138 sizeof(*records));
139 records[records_count++] = xstrdup(line);
140 }
141 free(line);
142 records = xrealloc(records, records_count, sizeof(*records));
143 if (records_count >= (1U << 24))
144 error(EXIT_FAILURE, 0, "too many records: %u", records_count);
145
146 qsort(records, records_count, sizeof(*records), comparator);
147 }
148
149 static void
150 print_uint8(FILE *fp, uint8_t v)
151 {
152 fprintf(fp, "%c", v);
153 }
154
155 static void
156 print_uint16(FILE *fp, uint16_t v)
157 {
158 fprintf(fp, "%c%c", v >> 8, v & 0xff);
159 }
160
161 static void
162 print_uint24(FILE *fp, uint32_t v)
163 {
164 fprintf(fp, "%c%c%c", (v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);
165 }
166
167 int
168 main(int ac, const char **av)
169 {
170 unsigned count, i, record_bytes, first_index = 0, prev_index = 0;
171 int min_offset, max_offset;
172 int *offsets;
173
174 if (ac < 2)
175 error(EXIT_FAILURE, 0, "insufficient arguments");
176 if (ac > 2)
177 error(EXIT_FAILURE, 0, "too many arguments");
178 record_bytes = atoi(av[1]);
179 if (record_bytes < 6 || record_bytes > 16)
180 error(EXIT_FAILURE, 0, "fingerprint size out of bounds");
181
182 read_stream(stdin, record_bytes);
183
184 /* initialize global records offset table */
185 offsets = xcalloc(65536, sizeof(*offsets));
186 for (count = 0; count < records_count; ++count, prev_index = i)
187 {
188 const char *r = records[count];
189
190 i = (((((c2u(r[0]) << 4) + c2u(r[1])) << 4) +
191 c2u(r[2])) << 4) + c2u(r[3]);
192 if (count == 0)
193 first_index = i;
194 else if (i == prev_index)
195 continue;
196 offsets[i] = count;
197 }
198
199 /* set offsets for indices without records */
200 if (offsets[65536 - 1] == 0)
201 offsets[65536 - 1] = records_count;
202 for (i = 65536 - 2; i > first_index; --i)
203 if (offsets[i] == 0)
204 offsets[i] = offsets[i + 1];
205
206 /* make global records offset table relative to
207 expected position assuming uniform distribution. */
208 for (i = 0, min_offset = 0, max_offset = 0; i < 65536; ++i)
209 {
210 offsets[i] -= (i * (unsigned long long) records_count) >> 16;
211 if (offsets[i] < min_offset)
212 min_offset = offsets[i];
213 if (offsets[i] > max_offset)
214 max_offset = offsets[i];
215 }
216 min_offset = -min_offset;
217 if (min_offset < 0)
218 error(EXIT_FAILURE, 0,
219 "invalid offset shift: %d", min_offset);
220 for (i = 0; i < 65536; ++i)
221 {
222 offsets[i] += min_offset;
223 if (offsets[i] < 0 || offsets[i] >= 65536)
224 error(EXIT_FAILURE, 0,
225 "offset overflow for index %#x: %d",
226 i, offsets[i]);
227 }
228 max_offset += min_offset;
229
230 /* Header, 16 bytes */
231
232 /* format version identifier */
233 printf("SSH-FP00");
234 /* index size, in bits */
235 print_uint8(stdout, 16);
236 /* offset size, in bits */
237 print_uint8(stdout, 16);
238 /* record size, in bits */
239 print_uint8(stdout, record_bytes * 8);
240 /* records count */
241 print_uint24(stdout, records_count);
242 /* offset shift */
243 print_uint16(stdout, min_offset);
244 fprintf(stderr, "records=%u, offset shift=%d, max offset=%d\n",
245 records_count, min_offset, max_offset);
246
247 /* Index, 65536 * 2 bytes */
248 for (i = 0; i < 65536; ++i)
249 print_uint16(stdout, offsets[i]);
250
251 /* Fingerprints, records_count * (record_bytes-2) bytes */
252 for (count = 0; count < records_count; ++count)
253 {
254 const char *r = records[count] + 4;
255
256 for (i = 0; i < record_bytes - 2; ++i)
257 print_uint8(stdout,
258 c2u(r[i * 2]) * 16 + c2u(r[i * 2 + 1]));
259 }
260
261 if (fclose(stdout))
262 error(EXIT_FAILURE, errno, "stdout");
263 return 0;
264 }
265
266
267
268 --
269 gentoo-commits@l.g.o mailing list