1 1.21 matt /* $NetBSD: utils.c,v 1.21 2012/03/20 18:50:30 matt Exp $ */ 2 1.1 elric 3 1.1 elric /*- 4 1.2 elric * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 5 1.1 elric * All rights reserved. 6 1.1 elric * 7 1.1 elric * This code is derived from software contributed to The NetBSD Foundation 8 1.1 elric * by Roland C. Dowdeswell. 9 1.1 elric * 10 1.1 elric * Redistribution and use in source and binary forms, with or without 11 1.1 elric * modification, are permitted provided that the following conditions 12 1.1 elric * are met: 13 1.1 elric * 1. Redistributions of source code must retain the above copyright 14 1.1 elric * notice, this list of conditions and the following disclaimer. 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 elric * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 elric * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 elric * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 elric * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 elric * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 elric * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 elric * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 elric * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 elric * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 elric * POSSIBILITY OF SUCH DAMAGE. 30 1.1 elric */ 31 1.1 elric 32 1.1 elric #include <sys/cdefs.h> 33 1.1 elric #ifndef lint 34 1.21 matt __RCSID("$NetBSD: utils.c,v 1.21 2012/03/20 18:50:30 matt Exp $"); 35 1.1 elric #endif 36 1.1 elric 37 1.2 elric #include <sys/param.h> 38 1.2 elric 39 1.2 elric #include <stdlib.h> 40 1.1 elric #include <string.h> 41 1.6 christos #include <err.h> 42 1.15 christos #include <util.h> 43 1.1 elric 44 1.2 elric /* include the resolver gunk in order that we can use b64 routines */ 45 1.2 elric #include <netinet/in.h> 46 1.2 elric #include <arpa/nameser.h> 47 1.2 elric #include <resolv.h> 48 1.2 elric 49 1.1 elric #include "utils.h" 50 1.1 elric 51 1.6 christos 52 1.1 elric /* just strsep(3), but skips empty fields. */ 53 1.1 elric 54 1.1 elric static char * 55 1.1 elric strsep_getnext(char **stringp, const char *delim) 56 1.1 elric { 57 1.1 elric char *ret; 58 1.1 elric 59 1.1 elric ret = strsep(stringp, delim); 60 1.1 elric while (ret && index(delim, *ret)) 61 1.1 elric ret = strsep(stringp, delim); 62 1.1 elric return ret; 63 1.1 elric } 64 1.1 elric 65 1.1 elric /* 66 1.1 elric * this function returns a dynamically sized char ** of the words 67 1.1 elric * in the line. the caller is responsible for both free(3)ing 68 1.1 elric * each word and the superstructure by calling words_free(). 69 1.1 elric */ 70 1.1 elric char ** 71 1.1 elric words(const char *line, int *num) 72 1.1 elric { 73 1.1 elric int i = 0; 74 1.1 elric int nwords = 0; 75 1.1 elric char *cur; 76 1.1 elric char **ret; 77 1.9 christos const char *tmp; 78 1.9 christos char *tmp1, *tmpf; 79 1.1 elric 80 1.1 elric *num = 0; 81 1.9 christos tmp = line; 82 1.1 elric if (tmp[0] == '\0') 83 1.1 elric return NULL; 84 1.1 elric while (tmp[0]) { 85 1.1 elric if ((tmp[1] == ' ' || tmp[1] == '\t' || tmp[1] == '\0') && 86 1.1 elric (tmp[0] != ' ' && tmp[0] != '\t')) 87 1.1 elric nwords++; 88 1.1 elric tmp++; 89 1.1 elric } 90 1.6 christos ret = emalloc((nwords+1) * sizeof(char *)); 91 1.9 christos tmp1 = tmpf = estrdup(line); 92 1.9 christos while ((cur = strsep_getnext(&tmpf, " \t")) != NULL) 93 1.6 christos ret[i++] = estrdup(cur); 94 1.1 elric ret[i] = NULL; 95 1.1 elric free(tmp1); 96 1.1 elric *num = nwords; 97 1.1 elric return ret; 98 1.1 elric } 99 1.1 elric 100 1.1 elric void 101 1.1 elric words_free(char **w, int num) 102 1.1 elric { 103 1.1 elric int i; 104 1.1 elric 105 1.1 elric for (i=0; i < num; i++) 106 1.1 elric free(w[i]); 107 1.1 elric } 108 1.1 elric 109 1.1 elric /* 110 1.1 elric * this is a simple xor that has the same calling conventions as 111 1.1 elric * memcpy(3). 112 1.1 elric */ 113 1.1 elric 114 1.1 elric void 115 1.1 elric memxor(void *res, const void *src, size_t len) 116 1.1 elric { 117 1.1 elric char *r; 118 1.1 elric const char *s; 119 1.16 cbiere size_t i; 120 1.1 elric 121 1.1 elric r = res; 122 1.1 elric s = src; 123 1.16 cbiere for (i = 0; i < len; i++) 124 1.1 elric r[i] ^= s[i]; 125 1.2 elric } 126 1.2 elric 127 1.2 elric /* 128 1.2 elric * well, a very simple set of string functions... 129 1.2 elric * 130 1.2 elric * The goal here is basically to manage length encoded strings, 131 1.2 elric * but just for safety we nul terminate them anyway. 132 1.2 elric */ 133 1.2 elric 134 1.2 elric /* for now we use a very simple encoding */ 135 1.2 elric 136 1.2 elric struct string { 137 1.2 elric char *text; 138 1.17 christos size_t length; 139 1.2 elric }; 140 1.2 elric 141 1.2 elric string_t * 142 1.21 matt string_zero(void) 143 1.19 elric { 144 1.19 elric string_t *out; 145 1.19 elric 146 1.19 elric out = emalloc(sizeof(*out)); 147 1.19 elric out->length = 0; 148 1.19 elric out->text = NULL; 149 1.19 elric return out; 150 1.19 elric } 151 1.19 elric 152 1.19 elric string_t * 153 1.17 christos string_new(const char *intext, size_t inlength) 154 1.2 elric { 155 1.2 elric string_t *out; 156 1.2 elric 157 1.6 christos out = emalloc(sizeof(*out)); 158 1.2 elric out->length = inlength; 159 1.6 christos out->text = emalloc(out->length + 1); 160 1.17 christos (void)memcpy(out->text, intext, out->length); 161 1.2 elric out->text[out->length] = '\0'; 162 1.2 elric return out; 163 1.2 elric } 164 1.2 elric 165 1.2 elric string_t * 166 1.2 elric string_dup(const string_t *in) 167 1.2 elric { 168 1.2 elric 169 1.2 elric return string_new(in->text, in->length); 170 1.2 elric } 171 1.2 elric 172 1.2 elric void 173 1.2 elric string_free(string_t *s) 174 1.2 elric { 175 1.2 elric 176 1.2 elric if (!s) 177 1.2 elric return; 178 1.6 christos free(s->text); 179 1.2 elric free(s); 180 1.2 elric } 181 1.2 elric 182 1.2 elric void 183 1.2 elric string_assign(string_t **lhs, string_t *rhs) 184 1.2 elric { 185 1.2 elric 186 1.2 elric string_free(*lhs); 187 1.2 elric *lhs = rhs; 188 1.2 elric } 189 1.2 elric 190 1.2 elric string_t * 191 1.2 elric string_add(const string_t *a1, const string_t *a2) 192 1.2 elric { 193 1.2 elric string_t *sum; 194 1.2 elric 195 1.6 christos sum = emalloc(sizeof(*sum)); 196 1.2 elric sum->length = a1->length + a2->length; 197 1.6 christos sum->text = emalloc(sum->length + 1); 198 1.17 christos (void)memcpy(sum->text, a1->text, a1->length); 199 1.17 christos (void)memcpy(sum->text + a1->length, a2->text, a2->length); 200 1.2 elric sum->text[sum->length] = '\0'; 201 1.2 elric return sum; 202 1.2 elric } 203 1.2 elric 204 1.2 elric string_t * 205 1.2 elric string_add_d(string_t *a1, string_t *a2) 206 1.2 elric { 207 1.2 elric string_t *sum; 208 1.2 elric 209 1.2 elric sum = string_add(a1, a2); 210 1.2 elric string_free(a1); 211 1.2 elric string_free(a2); 212 1.2 elric return sum; 213 1.2 elric } 214 1.2 elric 215 1.2 elric string_t * 216 1.2 elric string_fromcharstar(const char *in) 217 1.2 elric { 218 1.2 elric 219 1.2 elric return string_new(in, strlen(in)); 220 1.2 elric } 221 1.2 elric 222 1.2 elric const char * 223 1.2 elric string_tocharstar(const string_t *in) 224 1.2 elric { 225 1.2 elric 226 1.2 elric return in->text; 227 1.2 elric } 228 1.2 elric 229 1.2 elric string_t * 230 1.2 elric string_fromint(int in) 231 1.2 elric { 232 1.2 elric string_t *ret; 233 1.2 elric 234 1.6 christos ret = emalloc(sizeof(*ret)); 235 1.2 elric ret->length = asprintf(&ret->text, "%d", in); 236 1.17 christos if (ret->text == NULL) 237 1.6 christos err(1, NULL); 238 1.2 elric return ret; 239 1.2 elric } 240 1.2 elric 241 1.2 elric void 242 1.2 elric string_fprint(FILE *f, const string_t *s) 243 1.2 elric { 244 1.17 christos (void)fwrite(s->text, s->length, 1, f); 245 1.2 elric } 246 1.2 elric 247 1.2 elric struct bits { 248 1.17 christos size_t length; 249 1.2 elric char *text; 250 1.2 elric }; 251 1.2 elric 252 1.2 elric bits_t * 253 1.17 christos bits_new(const void *buf, size_t len) 254 1.2 elric { 255 1.2 elric bits_t *b; 256 1.2 elric 257 1.7 elric b = emalloc(sizeof(*b)); 258 1.2 elric b->length = len; 259 1.6 christos b->text = emalloc(BITS2BYTES(b->length)); 260 1.17 christos (void)memcpy(b->text, buf, BITS2BYTES(b->length)); 261 1.2 elric return b; 262 1.2 elric } 263 1.2 elric 264 1.2 elric bits_t * 265 1.2 elric bits_dup(const bits_t *in) 266 1.2 elric { 267 1.2 elric 268 1.2 elric return bits_new(in->text, in->length); 269 1.2 elric } 270 1.2 elric 271 1.2 elric void 272 1.2 elric bits_free(bits_t *b) 273 1.2 elric { 274 1.2 elric 275 1.2 elric if (!b) 276 1.2 elric return; 277 1.6 christos free(b->text); 278 1.2 elric free(b); 279 1.2 elric } 280 1.2 elric 281 1.2 elric void 282 1.2 elric bits_assign(bits_t **lhs, bits_t *rhs) 283 1.2 elric { 284 1.2 elric 285 1.2 elric bits_free(*lhs); 286 1.2 elric *lhs = rhs; 287 1.2 elric } 288 1.2 elric 289 1.2 elric const void * 290 1.2 elric bits_getbuf(bits_t *in) 291 1.2 elric { 292 1.2 elric 293 1.2 elric return in->text; 294 1.2 elric } 295 1.2 elric 296 1.17 christos size_t 297 1.2 elric bits_len(bits_t *in) 298 1.2 elric { 299 1.2 elric 300 1.2 elric return in->length; 301 1.3 cb } 302 1.3 cb 303 1.3 cb int 304 1.3 cb bits_match(const bits_t *b1, const bits_t *b2) 305 1.3 cb { 306 1.20 lukem size_t i; 307 1.3 cb 308 1.3 cb if (b1->length != b2->length) 309 1.3 cb return 0; 310 1.3 cb 311 1.3 cb for (i = 0; i < BITS2BYTES(b1->length); i++) 312 1.3 cb if (b1->text[i] != b2->text[i]) 313 1.3 cb return 0; 314 1.3 cb 315 1.3 cb return 1; 316 1.2 elric } 317 1.2 elric 318 1.2 elric bits_t * 319 1.2 elric bits_xor(const bits_t *x1, const bits_t *x2) 320 1.2 elric { 321 1.2 elric bits_t *b; 322 1.20 lukem size_t i; 323 1.2 elric 324 1.6 christos b = emalloc(sizeof(*b)); 325 1.2 elric b->length = MAX(x1->length, x2->length); 326 1.6 christos b->text = ecalloc(1, BITS2BYTES(b->length)); 327 1.2 elric for (i=0; i < BITS2BYTES(MIN(x1->length, x2->length)); i++) 328 1.2 elric b->text[i] = x1->text[i] ^ x2->text[i]; 329 1.2 elric return b; 330 1.2 elric } 331 1.2 elric 332 1.2 elric bits_t * 333 1.2 elric bits_xor_d(bits_t *x1, bits_t *x2) 334 1.2 elric { 335 1.2 elric bits_t *ret; 336 1.2 elric 337 1.2 elric ret = bits_xor(x1, x2); 338 1.2 elric bits_free(x1); 339 1.2 elric bits_free(x2); 340 1.2 elric return ret; 341 1.2 elric } 342 1.2 elric 343 1.2 elric /* 344 1.2 elric * bits_decode() reads an encoded base64 stream. We interpret 345 1.2 elric * the first 32 bits as an unsigned integer in network byte order 346 1.2 elric * specifying the number of bits in the stream to give a little 347 1.2 elric * resilience. 348 1.2 elric */ 349 1.2 elric 350 1.2 elric bits_t * 351 1.2 elric bits_decode(const string_t *in) 352 1.2 elric { 353 1.2 elric bits_t *ret; 354 1.17 christos size_t len; 355 1.17 christos size_t nbits; 356 1.17 christos u_int32_t *tmp; 357 1.2 elric 358 1.2 elric len = in->length; 359 1.6 christos tmp = emalloc(len); 360 1.2 elric 361 1.17 christos len = __b64_pton(in->text, (void *)tmp, len); 362 1.2 elric 363 1.17 christos if (len == (size_t)-1) { 364 1.17 christos warnx("bits_decode: mangled base64 stream"); 365 1.17 christos warnx(" %s", in->text); 366 1.12 christos free(tmp); 367 1.2 elric return NULL; 368 1.2 elric } 369 1.2 elric 370 1.17 christos nbits = ntohl(*tmp); 371 1.17 christos if (nbits > (len - sizeof(*tmp)) * NBBY) { 372 1.17 christos warnx("bits_decode: encoded bits claim to be " 373 1.17 christos "longer than they are (nbits=%zu, stream len=%zu bytes)", 374 1.17 christos nbits, len); 375 1.12 christos free(tmp); 376 1.2 elric return NULL; 377 1.2 elric } 378 1.2 elric 379 1.17 christos ret = bits_new(tmp + 1, nbits); 380 1.2 elric free(tmp); 381 1.2 elric return ret; 382 1.2 elric } 383 1.2 elric 384 1.2 elric bits_t * 385 1.2 elric bits_decode_d(string_t *in) 386 1.2 elric { 387 1.2 elric bits_t *ret; 388 1.2 elric 389 1.2 elric ret = bits_decode(in); 390 1.2 elric string_free(in); 391 1.2 elric return ret; 392 1.2 elric } 393 1.2 elric 394 1.2 elric string_t * 395 1.2 elric bits_encode(const bits_t *in) 396 1.2 elric { 397 1.2 elric string_t *ret; 398 1.17 christos size_t len; 399 1.2 elric char *out; 400 1.17 christos u_int32_t *tmp; 401 1.2 elric 402 1.2 elric if (!in) 403 1.2 elric return NULL; 404 1.2 elric 405 1.2 elric /* compute the total size of the input stream */ 406 1.17 christos len = BITS2BYTES(in->length) + sizeof(*tmp); 407 1.2 elric 408 1.6 christos tmp = emalloc(len); 409 1.6 christos out = emalloc(len * 2); 410 1.2 elric /* stuff the length up front */ 411 1.17 christos *tmp = htonl(in->length); 412 1.17 christos (void)memcpy(tmp + 1, in->text, len - sizeof(*tmp)); 413 1.2 elric 414 1.17 christos if ((len = __b64_ntop((void *)tmp, len, out, len * 2)) == (size_t)-1) { 415 1.13 christos free(out); 416 1.10 christos free(tmp); 417 1.10 christos return NULL; 418 1.10 christos } 419 1.2 elric ret = string_new(out, len); 420 1.2 elric free(tmp); 421 1.2 elric free(out); 422 1.2 elric return ret; 423 1.2 elric } 424 1.2 elric 425 1.2 elric string_t * 426 1.2 elric bits_encode_d(bits_t *in) 427 1.2 elric { 428 1.2 elric string_t *ret; 429 1.2 elric 430 1.2 elric ret = bits_encode(in); 431 1.2 elric bits_free(in); 432 1.2 elric return ret; 433 1.2 elric } 434 1.2 elric 435 1.2 elric bits_t * 436 1.17 christos bits_fget(FILE *f, size_t len) 437 1.2 elric { 438 1.2 elric bits_t *bits; 439 1.2 elric int ret; 440 1.2 elric 441 1.6 christos bits = emalloc(sizeof(*bits)); 442 1.2 elric bits->length = len; 443 1.6 christos bits->text = emalloc(BITS2BYTES(bits->length)); 444 1.2 elric ret = fread(bits->text, BITS2BYTES(bits->length), 1, f); 445 1.2 elric if (ret != 1) { 446 1.2 elric bits_free(bits); 447 1.2 elric return NULL; 448 1.2 elric } 449 1.2 elric return bits; 450 1.2 elric } 451 1.2 elric 452 1.2 elric bits_t * 453 1.17 christos bits_cget(const char *fn, size_t len) 454 1.2 elric { 455 1.2 elric bits_t *bits; 456 1.2 elric FILE *f; 457 1.2 elric 458 1.2 elric f = fopen(fn, "r"); 459 1.8 lukem if (!f) 460 1.2 elric return NULL; 461 1.2 elric 462 1.2 elric bits = bits_fget(f, len); 463 1.17 christos (void)fclose(f); 464 1.2 elric return bits; 465 1.2 elric } 466 1.2 elric 467 1.2 elric bits_t * 468 1.17 christos bits_getrandombits(size_t len, int hard) 469 1.2 elric { 470 1.2 elric 471 1.5 tv return bits_cget((hard ? "/dev/random" : "/dev/urandom"), len); 472 1.2 elric } 473 1.2 elric 474 1.2 elric void 475 1.2 elric bits_fprint(FILE *f, const bits_t *bits) 476 1.2 elric { 477 1.2 elric string_t *s; 478 1.2 elric 479 1.2 elric s = bits_encode(bits); 480 1.2 elric string_fprint(f, s); 481 1.2 elric free(s); 482 1.2 elric } 483