compats.c (43802B)
1 #include "config.h" 2 #if !HAVE_ERR 3 /* 4 * Copyright (c) 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <errno.h> 33 #include <stdarg.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 38 void 39 vwarnx(const char *fmt, va_list ap) 40 { 41 fprintf(stderr, "%s: ", getprogname()); 42 if (fmt != NULL) 43 vfprintf(stderr, fmt, ap); 44 } 45 46 void 47 vwarn(const char *fmt, va_list ap) 48 { 49 int sverrno; 50 51 sverrno = errno; 52 vwarnx(fmt, ap); 53 if (fmt != NULL) 54 fputs(": ", stderr); 55 fprintf(stderr, "%s\n", strerror(sverrno)); 56 } 57 58 void 59 err(int eval, const char *fmt, ...) 60 { 61 va_list ap; 62 63 va_start(ap, fmt); 64 vwarn(fmt, ap); 65 va_end(ap); 66 exit(eval); 67 } 68 69 void 70 errx(int eval, const char *fmt, ...) 71 { 72 va_list ap; 73 74 va_start(ap, fmt); 75 vwarnx(fmt, ap); 76 va_end(ap); 77 fputc('\n', stderr); 78 exit(eval); 79 } 80 81 void 82 warn(const char *fmt, ...) 83 { 84 va_list ap; 85 86 va_start(ap, fmt); 87 vwarn(fmt, ap); 88 va_end(ap); 89 } 90 91 void 92 warnx(const char *fmt, ...) 93 { 94 va_list ap; 95 96 va_start(ap, fmt); 97 vwarnx(fmt, ap); 98 va_end(ap); 99 fputc('\n', stderr); 100 } 101 #endif /* !HAVE_ERR */ 102 #if !HAVE_B64_NTOP 103 /* $OpenBSD$ */ 104 105 /* 106 * Copyright (c) 1996 by Internet Software Consortium. 107 * 108 * Permission to use, copy, modify, and distribute this software for any 109 * purpose with or without fee is hereby granted, provided that the above 110 * copyright notice and this permission notice appear in all copies. 111 * 112 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS 113 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES 114 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE 115 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 116 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 117 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 118 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 119 * SOFTWARE. 120 */ 121 122 /* 123 * Portions Copyright (c) 1995 by International Business Machines, Inc. 124 * 125 * International Business Machines, Inc. (hereinafter called IBM) grants 126 * permission under its copyrights to use, copy, modify, and distribute this 127 * Software with or without fee, provided that the above copyright notice and 128 * all paragraphs of this notice appear in all copies, and that the name of IBM 129 * not be used in connection with the marketing of any product incorporating 130 * the Software or modifications thereof, without specific, written prior 131 * permission. 132 * 133 * To the extent it has a right to do so, IBM grants an immunity from suit 134 * under its patents, if any, for the use, sale or manufacture of products to 135 * the extent that such products are used for performing Domain Name System 136 * dynamic updates in TCP/IP networks by means of the Software. No immunity is 137 * granted for any product per se or for any other function of any product. 138 * 139 * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, 140 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 141 * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, 142 * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING 143 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN 144 * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. 145 */ 146 147 #include <sys/types.h> 148 #include <sys/socket.h> 149 #include <netinet/in.h> 150 #include <arpa/inet.h> 151 #include <arpa/nameser.h> 152 153 #include <ctype.h> 154 #include <resolv.h> 155 #include <stdio.h> 156 157 #include <stdlib.h> 158 #include <string.h> 159 160 static const char b64_Base64[] = 161 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 162 static const char b64_Pad64 = '='; 163 164 /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) 165 The following encoding technique is taken from RFC 1521 by Borenstein 166 and Freed. It is reproduced here in a slightly edited form for 167 convenience. 168 169 A 65-character subset of US-ASCII is used, enabling 6 bits to be 170 represented per printable character. (The extra 65th character, "=", 171 is used to signify a special processing function.) 172 173 The encoding process represents 24-bit groups of input bits as output 174 strings of 4 encoded characters. Proceeding from left to right, a 175 24-bit input group is formed by concatenating 3 8-bit input groups. 176 These 24 bits are then treated as 4 concatenated 6-bit groups, each 177 of which is translated into a single digit in the base64 alphabet. 178 179 Each 6-bit group is used as an index into an array of 64 printable 180 characters. The character referenced by the index is placed in the 181 output string. 182 183 Table 1: The Base64 Alphabet 184 185 Value Encoding Value Encoding Value Encoding Value Encoding 186 0 A 17 R 34 i 51 z 187 1 B 18 S 35 j 52 0 188 2 C 19 T 36 k 53 1 189 3 D 20 U 37 l 54 2 190 4 E 21 V 38 m 55 3 191 5 F 22 W 39 n 56 4 192 6 G 23 X 40 o 57 5 193 7 H 24 Y 41 p 58 6 194 8 I 25 Z 42 q 59 7 195 9 J 26 a 43 r 60 8 196 10 K 27 b 44 s 61 9 197 11 L 28 c 45 t 62 + 198 12 M 29 d 46 u 63 / 199 13 N 30 e 47 v 200 14 O 31 f 48 w (pad) = 201 15 P 32 g 49 x 202 16 Q 33 h 50 y 203 204 Special processing is performed if fewer than 24 bits are available 205 at the end of the data being encoded. A full encoding quantum is 206 always completed at the end of a quantity. When fewer than 24 input 207 bits are available in an input group, zero bits are added (on the 208 right) to form an integral number of 6-bit groups. Padding at the 209 end of the data is performed using the '=' character. 210 211 Since all base64 input is an integral number of octets, only the 212 ------------------------------------------------- 213 following cases can arise: 214 215 (1) the final quantum of encoding input is an integral 216 multiple of 24 bits; here, the final unit of encoded 217 output will be an integral multiple of 4 characters 218 with no "=" padding, 219 (2) the final quantum of encoding input is exactly 8 bits; 220 here, the final unit of encoded output will be two 221 characters followed by two "=" padding characters, or 222 (3) the final quantum of encoding input is exactly 16 bits; 223 here, the final unit of encoded output will be three 224 characters followed by one "=" padding character. 225 */ 226 227 int 228 b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) 229 { 230 size_t datalength = 0; 231 u_char input[3]; 232 u_char output[4]; 233 size_t i; 234 235 while (2 < srclength) { 236 input[0] = *src++; 237 input[1] = *src++; 238 input[2] = *src++; 239 srclength -= 3; 240 241 output[0] = input[0] >> 2; 242 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 243 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 244 output[3] = input[2] & 0x3f; 245 246 if (datalength + 4 > targsize) 247 return (-1); 248 target[datalength++] = b64_Base64[output[0]]; 249 target[datalength++] = b64_Base64[output[1]]; 250 target[datalength++] = b64_Base64[output[2]]; 251 target[datalength++] = b64_Base64[output[3]]; 252 } 253 254 /* Now we worry about padding. */ 255 if (0 != srclength) { 256 /* Get what's left. */ 257 input[0] = input[1] = input[2] = '\0'; 258 for (i = 0; i < srclength; i++) 259 input[i] = *src++; 260 261 output[0] = input[0] >> 2; 262 output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); 263 output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); 264 265 if (datalength + 4 > targsize) 266 return (-1); 267 target[datalength++] = b64_Base64[output[0]]; 268 target[datalength++] = b64_Base64[output[1]]; 269 if (srclength == 1) 270 target[datalength++] = b64_Pad64; 271 else 272 target[datalength++] = b64_Base64[output[2]]; 273 target[datalength++] = b64_Pad64; 274 } 275 if (datalength >= targsize) 276 return (-1); 277 target[datalength] = '\0'; /* Returned value doesn't count \0. */ 278 return (datalength); 279 } 280 281 /* skips all whitespace anywhere. 282 converts characters, four at a time, starting at (or after) 283 src from base - 64 numbers into three 8 bit bytes in the target area. 284 it returns the number of data bytes stored at the target, or -1 on error. 285 */ 286 287 int 288 b64_pton(char const *src, u_char *target, size_t targsize) 289 { 290 int state, ch; 291 size_t tarindex; 292 u_char nextbyte; 293 char *pos; 294 295 state = 0; 296 tarindex = 0; 297 298 while ((ch = (unsigned char)*src++) != '\0') { 299 if (isspace(ch)) /* Skip whitespace anywhere. */ 300 continue; 301 302 if (ch == b64_Pad64) 303 break; 304 305 pos = strchr(b64_Base64, ch); 306 if (pos == 0) /* A non-base64 character. */ 307 return (-1); 308 309 switch (state) { 310 case 0: 311 if (target) { 312 if (tarindex >= targsize) 313 return (-1); 314 target[tarindex] = (pos - b64_Base64) << 2; 315 } 316 state = 1; 317 break; 318 case 1: 319 if (target) { 320 if (tarindex >= targsize) 321 return (-1); 322 target[tarindex] |= (pos - b64_Base64) >> 4; 323 nextbyte = ((pos - b64_Base64) & 0x0f) << 4; 324 if (tarindex + 1 < targsize) 325 target[tarindex+1] = nextbyte; 326 else if (nextbyte) 327 return (-1); 328 } 329 tarindex++; 330 state = 2; 331 break; 332 case 2: 333 if (target) { 334 if (tarindex >= targsize) 335 return (-1); 336 target[tarindex] |= (pos - b64_Base64) >> 2; 337 nextbyte = ((pos - b64_Base64) & 0x03) << 6; 338 if (tarindex + 1 < targsize) 339 target[tarindex+1] = nextbyte; 340 else if (nextbyte) 341 return (-1); 342 } 343 tarindex++; 344 state = 3; 345 break; 346 case 3: 347 if (target) { 348 if (tarindex >= targsize) 349 return (-1); 350 target[tarindex] |= (pos - b64_Base64); 351 } 352 tarindex++; 353 state = 0; 354 break; 355 } 356 } 357 358 /* 359 * We are done decoding Base-64 chars. Let's see if we ended 360 * on a byte boundary, and/or with erroneous trailing characters. 361 */ 362 363 if (ch == b64_Pad64) { /* We got a pad char. */ 364 ch = (unsigned char)*src++; /* Skip it, get next. */ 365 switch (state) { 366 case 0: /* Invalid = in first position */ 367 case 1: /* Invalid = in second position */ 368 return (-1); 369 370 case 2: /* Valid, means one byte of info */ 371 /* Skip any number of spaces. */ 372 for (; ch != '\0'; ch = (unsigned char)*src++) 373 if (!isspace(ch)) 374 break; 375 /* Make sure there is another trailing = sign. */ 376 if (ch != b64_Pad64) 377 return (-1); 378 ch = (unsigned char)*src++; /* Skip the = */ 379 /* Fall through to "single trailing =" case. */ 380 /* FALLTHROUGH */ 381 382 case 3: /* Valid, means two bytes of info */ 383 /* 384 * We know this char is an =. Is there anything but 385 * whitespace after it? 386 */ 387 for (; ch != '\0'; ch = (unsigned char)*src++) 388 if (!isspace(ch)) 389 return (-1); 390 391 /* 392 * Now make sure for cases 2 and 3 that the "extra" 393 * bits that slopped past the last full byte were 394 * zeros. If we don't check them, they become a 395 * subliminal channel. 396 */ 397 if (target && tarindex < targsize && 398 target[tarindex] != 0) 399 return (-1); 400 } 401 } else { 402 /* 403 * We ended by seeing the end of the string. Make sure we 404 * have no partial bytes lying around. 405 */ 406 if (state != 0) 407 return (-1); 408 } 409 410 return (tarindex); 411 } 412 #endif /* !HAVE_B64_NTOP */ 413 #if !HAVE_EXPLICIT_BZERO 414 /* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ 415 /* 416 * Public domain. 417 * Written by Ted Unangst 418 */ 419 420 #include <string.h> 421 422 /* 423 * explicit_bzero - don't let the compiler optimize away bzero 424 */ 425 426 #if HAVE_MEMSET_S 427 428 void 429 explicit_bzero(void *p, size_t n) 430 { 431 if (n == 0) 432 return; 433 (void)memset_s(p, n, 0, n); 434 } 435 436 #else /* HAVE_MEMSET_S */ 437 438 /* 439 * Indirect bzero through a volatile pointer to hopefully avoid 440 * dead-store optimisation eliminating the call. 441 */ 442 static void (* volatile ssh_bzero)(void *, size_t) = bzero; 443 444 void 445 explicit_bzero(void *p, size_t n) 446 { 447 if (n == 0) 448 return; 449 /* 450 * clang -fsanitize=memory needs to intercept memset-like functions 451 * to correctly detect memory initialisation. Make sure one is called 452 * directly since our indirection trick above sucessfully confuses it. 453 */ 454 #if defined(__has_feature) 455 # if __has_feature(memory_sanitizer) 456 memset(p, 0, n); 457 # endif 458 #endif 459 460 ssh_bzero(p, n); 461 } 462 463 #endif /* HAVE_MEMSET_S */ 464 #endif /* !HAVE_EXPLICIT_BZERO */ 465 #if !HAVE_GETPROGNAME 466 /* 467 * Copyright (c) 2016 Nicholas Marriott <nicholas.marriott@gmail.com> 468 * Copyright (c) 2017 Kristaps Dzonsons <kristaps@bsd.lv> 469 * Copyright (c) 2020 Stephen Gregoratto <dev@sgregoratto.me> 470 * 471 * Permission to use, copy, modify, and distribute this software for any 472 * purpose with or without fee is hereby granted, provided that the above 473 * copyright notice and this permission notice appear in all copies. 474 * 475 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 476 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 477 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 478 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 479 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 480 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 481 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 482 */ 483 484 #include <sys/types.h> 485 486 #include <errno.h> 487 488 #if HAVE_GETEXECNAME 489 #include <stdlib.h> 490 const char * 491 getprogname(void) 492 { 493 return getexecname(); 494 } 495 #elif HAVE_PROGRAM_INVOCATION_SHORT_NAME 496 const char * 497 getprogname(void) 498 { 499 return (program_invocation_short_name); 500 } 501 #elif HAVE___PROGNAME 502 const char * 503 getprogname(void) 504 { 505 extern char *__progname; 506 507 return (__progname); 508 } 509 #else 510 #error No getprogname available. 511 #endif 512 #endif /* !HAVE_GETPROGNAME */ 513 #if !HAVE_MD5 514 /* 515 * This code implements the MD5 message-digest algorithm. 516 * The algorithm is due to Ron Rivest. This code was 517 * written by Colin Plumb in 1993, no copyright is claimed. 518 * This code is in the public domain; do with it what you wish. 519 * 520 * Equivalent code is available from RSA Data Security, Inc. 521 * This code has been tested against that, and is equivalent, 522 * except that you don't need to include two pages of legalese 523 * with every copy. 524 * 525 * To compute the message digest of a chunk of bytes, declare an 526 * MD5Context structure, pass it to MD5Init, call MD5Update as 527 * needed on buffers full of bytes, and then call MD5Final, which 528 * will fill a supplied 16-byte array with the digest. 529 */ 530 531 #include <sys/types.h> 532 #include <stdlib.h> 533 #include <string.h> 534 535 #define PUT_64BIT_LE(cp, value) do { \ 536 (cp)[7] = (value) >> 56; \ 537 (cp)[6] = (value) >> 48; \ 538 (cp)[5] = (value) >> 40; \ 539 (cp)[4] = (value) >> 32; \ 540 (cp)[3] = (value) >> 24; \ 541 (cp)[2] = (value) >> 16; \ 542 (cp)[1] = (value) >> 8; \ 543 (cp)[0] = (value); } while (0) 544 545 #define PUT_32BIT_LE(cp, value) do { \ 546 (cp)[3] = (value) >> 24; \ 547 (cp)[2] = (value) >> 16; \ 548 (cp)[1] = (value) >> 8; \ 549 (cp)[0] = (value); } while (0) 550 551 static u_int8_t PADDING[MD5_BLOCK_LENGTH] = { 552 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 553 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 554 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 555 }; 556 557 /* 558 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 559 * initialization constants. 560 */ 561 void 562 MD5Init(MD5_CTX *ctx) 563 { 564 ctx->count = 0; 565 ctx->state[0] = 0x67452301; 566 ctx->state[1] = 0xefcdab89; 567 ctx->state[2] = 0x98badcfe; 568 ctx->state[3] = 0x10325476; 569 } 570 571 /* 572 * Update context to reflect the concatenation of another buffer full 573 * of bytes. 574 */ 575 void 576 MD5Update(MD5_CTX *ctx, const unsigned char *input, size_t len) 577 { 578 size_t have, need; 579 580 /* Check how many bytes we already have and how many more we need. */ 581 have = (size_t)((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 582 need = MD5_BLOCK_LENGTH - have; 583 584 /* Update bitcount */ 585 ctx->count += (u_int64_t)len << 3; 586 587 if (len >= need) { 588 if (have != 0) { 589 memcpy(ctx->buffer + have, input, need); 590 MD5Transform(ctx->state, ctx->buffer); 591 input += need; 592 len -= need; 593 have = 0; 594 } 595 596 /* Process data in MD5_BLOCK_LENGTH-byte chunks. */ 597 while (len >= MD5_BLOCK_LENGTH) { 598 MD5Transform(ctx->state, input); 599 input += MD5_BLOCK_LENGTH; 600 len -= MD5_BLOCK_LENGTH; 601 } 602 } 603 604 /* Handle any remaining bytes of data. */ 605 if (len != 0) 606 memcpy(ctx->buffer + have, input, len); 607 } 608 609 /* 610 * Pad pad to 64-byte boundary with the bit pattern 611 * 1 0* (64-bit count of bits processed, MSB-first) 612 */ 613 void 614 MD5Pad(MD5_CTX *ctx) 615 { 616 u_int8_t count[8]; 617 size_t padlen; 618 619 /* Convert count to 8 bytes in little endian order. */ 620 PUT_64BIT_LE(count, ctx->count); 621 622 /* Pad out to 56 mod 64. */ 623 padlen = MD5_BLOCK_LENGTH - 624 ((ctx->count >> 3) & (MD5_BLOCK_LENGTH - 1)); 625 if (padlen < 1 + 8) 626 padlen += MD5_BLOCK_LENGTH; 627 MD5Update(ctx, PADDING, padlen - 8); /* padlen - 8 <= 64 */ 628 MD5Update(ctx, count, 8); 629 } 630 631 /* 632 * Final wrapup--call MD5Pad, fill in digest and zero out ctx. 633 */ 634 void 635 MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], MD5_CTX *ctx) 636 { 637 int i; 638 639 MD5Pad(ctx); 640 for (i = 0; i < 4; i++) 641 PUT_32BIT_LE(digest + i * 4, ctx->state[i]); 642 memset(ctx, 0, sizeof(*ctx)); 643 } 644 645 646 /* The four core functions - F1 is optimized somewhat */ 647 648 /* #define F1(x, y, z) (x & y | ~x & z) */ 649 #define F1(x, y, z) (z ^ (x & (y ^ z))) 650 #define F2(x, y, z) F1(z, x, y) 651 #define F3(x, y, z) (x ^ y ^ z) 652 #define F4(x, y, z) (y ^ (x | ~z)) 653 654 /* This is the central step in the MD5 algorithm. */ 655 #define MD5STEP(f, w, x, y, z, data, s) \ 656 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) 657 658 /* 659 * The core of the MD5 algorithm, this alters an existing MD5 hash to 660 * reflect the addition of 16 longwords of new data. MD5Update blocks 661 * the data and converts bytes into longwords for this routine. 662 */ 663 void 664 MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH]) 665 { 666 u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; 667 668 #if BYTE_ORDER == LITTLE_ENDIAN 669 memcpy(in, block, sizeof(in)); 670 #else 671 for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { 672 in[a] = (u_int32_t)( 673 (u_int32_t)(block[a * 4 + 0]) | 674 (u_int32_t)(block[a * 4 + 1]) << 8 | 675 (u_int32_t)(block[a * 4 + 2]) << 16 | 676 (u_int32_t)(block[a * 4 + 3]) << 24); 677 } 678 #endif 679 680 a = state[0]; 681 b = state[1]; 682 c = state[2]; 683 d = state[3]; 684 685 MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); 686 MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); 687 MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); 688 MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); 689 MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); 690 MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); 691 MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); 692 MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); 693 MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); 694 MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); 695 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); 696 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); 697 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); 698 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); 699 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); 700 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); 701 702 MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); 703 MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); 704 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); 705 MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); 706 MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); 707 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); 708 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); 709 MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); 710 MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); 711 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); 712 MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); 713 MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); 714 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); 715 MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); 716 MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); 717 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); 718 719 MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); 720 MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); 721 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); 722 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); 723 MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); 724 MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); 725 MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); 726 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); 727 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); 728 MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); 729 MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); 730 MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); 731 MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); 732 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); 733 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); 734 MD5STEP(F3, b, c, d, a, in[2 ] + 0xc4ac5665, 23); 735 736 MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); 737 MD5STEP(F4, d, a, b, c, in[7 ] + 0x432aff97, 10); 738 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); 739 MD5STEP(F4, b, c, d, a, in[5 ] + 0xfc93a039, 21); 740 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); 741 MD5STEP(F4, d, a, b, c, in[3 ] + 0x8f0ccc92, 10); 742 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); 743 MD5STEP(F4, b, c, d, a, in[1 ] + 0x85845dd1, 21); 744 MD5STEP(F4, a, b, c, d, in[8 ] + 0x6fa87e4f, 6); 745 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); 746 MD5STEP(F4, c, d, a, b, in[6 ] + 0xa3014314, 15); 747 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); 748 MD5STEP(F4, a, b, c, d, in[4 ] + 0xf7537e82, 6); 749 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); 750 MD5STEP(F4, c, d, a, b, in[2 ] + 0x2ad7d2bb, 15); 751 MD5STEP(F4, b, c, d, a, in[9 ] + 0xeb86d391, 21); 752 753 state[0] += a; 754 state[1] += b; 755 state[2] += c; 756 state[3] += d; 757 } 758 759 char * 760 MD5End(MD5_CTX *ctx, char *buf) 761 { 762 int i; 763 unsigned char digest[MD5_DIGEST_LENGTH]; 764 static const char hex[]="0123456789abcdef"; 765 766 if (!buf) 767 buf = malloc(2*MD5_DIGEST_LENGTH + 1); 768 if (!buf) 769 return 0; 770 MD5Final(digest, ctx); 771 for (i = 0; i < MD5_DIGEST_LENGTH; i++) { 772 buf[i+i] = hex[digest[i] >> 4]; 773 buf[i+i+1] = hex[digest[i] & 0x0f]; 774 } 775 buf[i+i] = '\0'; 776 return buf; 777 } 778 #endif /* !HAVE_MD5 */ 779 #if !HAVE_MEMMEM 780 /*- 781 * Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com> 782 * 783 * Redistribution and use in source and binary forms, with or without 784 * modification, are permitted provided that the following conditions 785 * are met: 786 * 1. Redistributions of source code must retain the above copyright 787 * notice, this list of conditions and the following disclaimer. 788 * 2. Redistributions in binary form must reproduce the above copyright 789 * notice, this list of conditions and the following disclaimer in 790 * the documentation and/or other materials provided with the 791 * distribution. 792 * 3. The name of the author may not be used to endorse or promote 793 * products derived from this software without specific prior written 794 * permission. 795 * 796 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 797 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 798 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 799 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 800 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 801 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 802 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 803 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 804 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 805 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 806 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 807 */ 808 /* 809 * Find the first occurrence of the byte string s in byte string l. 810 */ 811 void * 812 memmem(const void *l, size_t l_len, const void *s, size_t s_len) 813 { 814 const char *cur, *last; 815 const char *cl = l; 816 const char *cs = s; 817 818 /* a zero length needle should just return the haystack */ 819 if (l_len == 0) 820 return (void *)cl; 821 822 /* "s" must be smaller or equal to "l" */ 823 if (l_len < s_len) 824 return NULL; 825 826 /* special case where s_len == 1 */ 827 if (s_len == 1) 828 return memchr(l, *cs, l_len); 829 830 /* the last position where its possible to find "s" in "l" */ 831 last = cl + l_len - s_len; 832 833 for (cur = cl; cur <= last; cur++) 834 if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0) 835 return (void *)cur; 836 837 return NULL; 838 } 839 #endif /* !HAVE_MEMMEM */ 840 #if !HAVE_MEMRCHR 841 /* 842 * Copyright (c) 2007 Todd C. Miller <Todd.Miller@courtesan.com> 843 * 844 * Permission to use, copy, modify, and distribute this software for any 845 * purpose with or without fee is hereby granted, provided that the above 846 * copyright notice and this permission notice appear in all copies. 847 * 848 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 849 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 850 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 851 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 852 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 853 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 854 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 855 * 856 */ 857 858 #include <string.h> 859 860 /* 861 * Reverse memchr() 862 * Find the last occurrence of 'c' in the buffer 's' of size 'n'. 863 */ 864 void * 865 memrchr(const void *s, int c, size_t n) 866 { 867 const unsigned char *cp; 868 869 if (n != 0) { 870 cp = (unsigned char *)s + n; 871 do { 872 if (*(--cp) == (unsigned char)c) 873 return((void *)cp); 874 } while (--n != 0); 875 } 876 return(NULL); 877 } 878 #endif /* !HAVE_MEMRCHR */ 879 #if !HAVE_READPASSPHRASE 880 /* 881 * Original: readpassphrase.c in OpenSSH portable 882 */ 883 /* 884 * Copyright (c) 2000-2002, 2007, 2010 885 * Todd C. Miller <millert@openbsd.org> 886 * 887 * Permission to use, copy, modify, and distribute this software for any 888 * purpose with or without fee is hereby granted, provided that the above 889 * copyright notice and this permission notice appear in all copies. 890 * 891 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 892 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 893 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 894 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 895 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 896 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 897 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 898 * 899 * Sponsored in part by the Defense Advanced Research Projects 900 * Agency (DARPA) and Air Force Research Laboratory, Air Force 901 * Materiel Command, USAF, under agreement number F39502-99-1-0512. 902 */ 903 904 #include <ctype.h> 905 #include <errno.h> 906 #include <fcntl.h> 907 #include <paths.h> 908 #include <pwd.h> 909 #include <signal.h> 910 #include <string.h> 911 #include <termios.h> 912 #include <unistd.h> 913 914 #if defined(_NSIG) 915 static volatile sig_atomic_t readpassphrase_signo[_NSIG]; 916 #else 917 static volatile sig_atomic_t readpassphrase_signo[NSIG]; 918 #endif 919 920 static void 921 readpassphrase_handler(int s) 922 { 923 924 readpassphrase_signo[s] = 1; 925 } 926 927 char * 928 readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags) 929 { 930 ssize_t nr; 931 int input, output, save_errno, i, need_restart; 932 char ch, *p, *end; 933 struct termios term, oterm; 934 struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm; 935 struct sigaction savetstp, savettin, savettou, savepipe; 936 /* If we don't have TCSASOFT define it so that ORing it it below is a no-op. */ 937 #ifndef TCSASOFT 938 const int tcasoft = 0; 939 #else 940 const int tcasoft = TCASOFT; 941 #endif 942 943 /* I suppose we could alloc on demand in this case (XXX). */ 944 if (bufsiz == 0) { 945 errno = EINVAL; 946 return(NULL); 947 } 948 949 restart: 950 for (i = 0; i < _NSIG; i++) 951 readpassphrase_signo[i] = 0; 952 nr = -1; 953 save_errno = 0; 954 need_restart = 0; 955 /* 956 * Read and write to /dev/tty if available. If not, read from 957 * stdin and write to stderr unless a tty is required. 958 */ 959 if ((flags & RPP_STDIN) || 960 (input = output = open(_PATH_TTY, O_RDWR)) == -1) { 961 if (flags & RPP_REQUIRE_TTY) { 962 errno = ENOTTY; 963 return(NULL); 964 } 965 input = STDIN_FILENO; 966 output = STDERR_FILENO; 967 } 968 969 /* 970 * Turn off echo if possible. 971 * If we are using a tty but are not the foreground pgrp this will 972 * generate SIGTTOU, so do it *before* installing the signal handlers. 973 */ 974 if (input != STDIN_FILENO && tcgetattr(input, &oterm) == 0) { 975 memcpy(&term, &oterm, sizeof(term)); 976 if (!(flags & RPP_ECHO_ON)) 977 term.c_lflag &= ~(ECHO | ECHONL); 978 #ifdef VSTATUS 979 if (term.c_cc[VSTATUS] != _POSIX_VDISABLE) 980 term.c_cc[VSTATUS] = _POSIX_VDISABLE; 981 #endif 982 (void)tcsetattr(input, TCSAFLUSH|tcasoft, &term); 983 } else { 984 memset(&term, 0, sizeof(term)); 985 term.c_lflag |= ECHO; 986 memset(&oterm, 0, sizeof(oterm)); 987 oterm.c_lflag |= ECHO; 988 } 989 990 /* 991 * Catch signals that would otherwise cause the user to end 992 * up with echo turned off in the shell. Don't worry about 993 * things like SIGXCPU and SIGVTALRM for now. 994 */ 995 sigemptyset(&sa.sa_mask); 996 sa.sa_flags = 0; /* don't restart system calls */ 997 sa.sa_handler = readpassphrase_handler; 998 (void)sigaction(SIGALRM, &sa, &savealrm); 999 (void)sigaction(SIGHUP, &sa, &savehup); 1000 (void)sigaction(SIGINT, &sa, &saveint); 1001 (void)sigaction(SIGPIPE, &sa, &savepipe); 1002 (void)sigaction(SIGQUIT, &sa, &savequit); 1003 (void)sigaction(SIGTERM, &sa, &saveterm); 1004 (void)sigaction(SIGTSTP, &sa, &savetstp); 1005 (void)sigaction(SIGTTIN, &sa, &savettin); 1006 (void)sigaction(SIGTTOU, &sa, &savettou); 1007 1008 if (!(flags & RPP_STDIN)) 1009 (void)write(output, prompt, strlen(prompt)); 1010 end = buf + bufsiz - 1; 1011 p = buf; 1012 while ((nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { 1013 if (p < end) { 1014 if ((flags & RPP_SEVENBIT)) 1015 ch &= 0x7f; 1016 if (isalpha((unsigned char)ch)) { 1017 if ((flags & RPP_FORCELOWER)) 1018 ch = (char)tolower((unsigned char)ch); 1019 if ((flags & RPP_FORCEUPPER)) 1020 ch = (char)toupper((unsigned char)ch); 1021 } 1022 *p++ = ch; 1023 } 1024 } 1025 *p = '\0'; 1026 save_errno = errno; 1027 if (!(term.c_lflag & ECHO)) 1028 (void)write(output, "\n", 1); 1029 1030 /* Restore old terminal settings and signals. */ 1031 if (memcmp(&term, &oterm, sizeof(term)) != 0) { 1032 const int sigttou = readpassphrase_signo[SIGTTOU]; 1033 1034 /* Ignore SIGTTOU generated when we are not the fg pgrp. */ 1035 while (tcsetattr(input, TCSAFLUSH|tcasoft, &oterm) == -1 && 1036 errno == EINTR && !readpassphrase_signo[SIGTTOU]) 1037 continue; 1038 readpassphrase_signo[SIGTTOU] = sigttou; 1039 } 1040 (void)sigaction(SIGALRM, &savealrm, NULL); 1041 (void)sigaction(SIGHUP, &savehup, NULL); 1042 (void)sigaction(SIGINT, &saveint, NULL); 1043 (void)sigaction(SIGQUIT, &savequit, NULL); 1044 (void)sigaction(SIGPIPE, &savepipe, NULL); 1045 (void)sigaction(SIGTERM, &saveterm, NULL); 1046 (void)sigaction(SIGTSTP, &savetstp, NULL); 1047 (void)sigaction(SIGTTIN, &savettin, NULL); 1048 (void)sigaction(SIGTTOU, &savettou, NULL); 1049 if (input != STDIN_FILENO) 1050 (void)close(input); 1051 1052 /* 1053 * If we were interrupted by a signal, resend it to ourselves 1054 * now that we have restored the signal handlers. 1055 */ 1056 for (i = 0; i < _NSIG; i++) { 1057 if (readpassphrase_signo[i]) { 1058 kill(getpid(), i); 1059 switch (i) { 1060 case SIGTSTP: 1061 case SIGTTIN: 1062 case SIGTTOU: 1063 need_restart = 1; 1064 } 1065 } 1066 } 1067 if (need_restart) 1068 goto restart; 1069 1070 if (save_errno) 1071 errno = save_errno; 1072 return(nr == -1 ? NULL : buf); 1073 } 1074 #endif /* !HAVE_READPASSPHRASE */ 1075 #if !HAVE_REALLOCARRAY 1076 /* 1077 * Copyright (c) 2008 Otto Moerbeek <otto@drijf.net> 1078 * 1079 * Permission to use, copy, modify, and distribute this software for any 1080 * purpose with or without fee is hereby granted, provided that the above 1081 * copyright notice and this permission notice appear in all copies. 1082 * 1083 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1084 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1085 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1086 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1087 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1088 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1089 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1090 */ 1091 1092 #include <sys/types.h> 1093 #include <errno.h> 1094 #include <stdint.h> 1095 #include <stdlib.h> 1096 1097 /* 1098 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 1099 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 1100 */ 1101 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 1102 1103 void * 1104 reallocarray(void *optr, size_t nmemb, size_t size) 1105 { 1106 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 1107 nmemb > 0 && SIZE_MAX / nmemb < size) { 1108 errno = ENOMEM; 1109 return NULL; 1110 } 1111 return realloc(optr, size * nmemb); 1112 } 1113 #endif /* !HAVE_REALLOCARRAY */ 1114 #if !HAVE_RECALLOCARRAY 1115 /* 1116 * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net> 1117 * 1118 * Permission to use, copy, modify, and distribute this software for any 1119 * purpose with or without fee is hereby granted, provided that the above 1120 * copyright notice and this permission notice appear in all copies. 1121 * 1122 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1123 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1124 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1125 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1126 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1127 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1128 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1129 */ 1130 1131 /* OPENBSD ORIGINAL: lib/libc/stdlib/recallocarray.c */ 1132 1133 #include <errno.h> 1134 #include <stdlib.h> 1135 #include <stdint.h> 1136 #include <string.h> 1137 #include <unistd.h> 1138 1139 /* 1140 * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX 1141 * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW 1142 */ 1143 #define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) 1144 1145 void * 1146 recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) 1147 { 1148 size_t oldsize, newsize; 1149 void *newptr; 1150 1151 if (ptr == NULL) 1152 return calloc(newnmemb, size); 1153 1154 if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 1155 newnmemb > 0 && SIZE_MAX / newnmemb < size) { 1156 errno = ENOMEM; 1157 return NULL; 1158 } 1159 newsize = newnmemb * size; 1160 1161 if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && 1162 oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { 1163 errno = EINVAL; 1164 return NULL; 1165 } 1166 oldsize = oldnmemb * size; 1167 1168 /* 1169 * Don't bother too much if we're shrinking just a bit, 1170 * we do not shrink for series of small steps, oh well. 1171 */ 1172 if (newsize <= oldsize) { 1173 size_t d = oldsize - newsize; 1174 1175 if (d < oldsize / 2 && d < (size_t)getpagesize()) { 1176 memset((char *)ptr + newsize, 0, d); 1177 return ptr; 1178 } 1179 } 1180 1181 newptr = malloc(newsize); 1182 if (newptr == NULL) 1183 return NULL; 1184 1185 if (newsize > oldsize) { 1186 memcpy(newptr, ptr, oldsize); 1187 memset((char *)newptr + oldsize, 0, newsize - oldsize); 1188 } else 1189 memcpy(newptr, ptr, newsize); 1190 1191 explicit_bzero(ptr, oldsize); 1192 free(ptr); 1193 1194 return newptr; 1195 } 1196 #endif /* !HAVE_RECALLOCARRAY */ 1197 #if !HAVE_STRLCAT 1198 /* 1199 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 1200 * 1201 * Permission to use, copy, modify, and distribute this software for any 1202 * purpose with or without fee is hereby granted, provided that the above 1203 * copyright notice and this permission notice appear in all copies. 1204 * 1205 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1206 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1207 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1208 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1209 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1210 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1211 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1212 */ 1213 1214 #include <sys/types.h> 1215 #include <string.h> 1216 1217 /* 1218 * Appends src to string dst of size siz (unlike strncat, siz is the 1219 * full size of dst, not space left). At most siz-1 characters 1220 * will be copied. Always NUL terminates (unless siz <= strlen(dst)). 1221 * Returns strlen(src) + MIN(siz, strlen(initial dst)). 1222 * If retval >= siz, truncation occurred. 1223 */ 1224 size_t 1225 strlcat(char *dst, const char *src, size_t siz) 1226 { 1227 char *d = dst; 1228 const char *s = src; 1229 size_t n = siz; 1230 size_t dlen; 1231 1232 /* Find the end of dst and adjust bytes left but don't go past end */ 1233 while (n-- != 0 && *d != '\0') 1234 d++; 1235 dlen = d - dst; 1236 n = siz - dlen; 1237 1238 if (n == 0) 1239 return(dlen + strlen(s)); 1240 while (*s != '\0') { 1241 if (n != 1) { 1242 *d++ = *s; 1243 n--; 1244 } 1245 s++; 1246 } 1247 *d = '\0'; 1248 1249 return(dlen + (s - src)); /* count does not include NUL */ 1250 } 1251 #endif /* !HAVE_STRLCAT */ 1252 #if !HAVE_STRLCPY 1253 /* 1254 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> 1255 * 1256 * Permission to use, copy, modify, and distribute this software for any 1257 * purpose with or without fee is hereby granted, provided that the above 1258 * copyright notice and this permission notice appear in all copies. 1259 * 1260 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1261 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1262 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1263 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1264 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1265 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1266 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1267 */ 1268 1269 #include <sys/types.h> 1270 #include <string.h> 1271 1272 /* 1273 * Copy src to string dst of size siz. At most siz-1 characters 1274 * will be copied. Always NUL terminates (unless siz == 0). 1275 * Returns strlen(src); if retval >= siz, truncation occurred. 1276 */ 1277 size_t 1278 strlcpy(char *dst, const char *src, size_t siz) 1279 { 1280 char *d = dst; 1281 const char *s = src; 1282 size_t n = siz; 1283 1284 /* Copy as many bytes as will fit */ 1285 if (n != 0) { 1286 while (--n != 0) { 1287 if ((*d++ = *s++) == '\0') 1288 break; 1289 } 1290 } 1291 1292 /* Not enough room in dst, add NUL and traverse rest of src */ 1293 if (n == 0) { 1294 if (siz != 0) 1295 *d = '\0'; /* NUL-terminate dst */ 1296 while (*s++) 1297 ; 1298 } 1299 1300 return(s - src - 1); /* count does not include NUL */ 1301 } 1302 #endif /* !HAVE_STRLCPY */ 1303 #if !HAVE_STRNDUP 1304 /* $OpenBSD$ */ 1305 /* 1306 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> 1307 * 1308 * Permission to use, copy, modify, and distribute this software for any 1309 * purpose with or without fee is hereby granted, provided that the above 1310 * copyright notice and this permission notice appear in all copies. 1311 * 1312 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1313 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1314 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1315 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1316 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1317 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1318 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1319 */ 1320 1321 #include <sys/types.h> 1322 1323 #include <stddef.h> 1324 #include <stdlib.h> 1325 #include <string.h> 1326 1327 char * 1328 strndup(const char *str, size_t maxlen) 1329 { 1330 char *copy; 1331 size_t len; 1332 1333 len = strnlen(str, maxlen); 1334 copy = malloc(len + 1); 1335 if (copy != NULL) { 1336 (void)memcpy(copy, str, len); 1337 copy[len] = '\0'; 1338 } 1339 1340 return copy; 1341 } 1342 #endif /* !HAVE_STRNDUP */ 1343 #if !HAVE_STRNLEN 1344 /* $OpenBSD$ */ 1345 1346 /* 1347 * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> 1348 * 1349 * Permission to use, copy, modify, and distribute this software for any 1350 * purpose with or without fee is hereby granted, provided that the above 1351 * copyright notice and this permission notice appear in all copies. 1352 * 1353 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1354 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1355 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1356 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1357 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1358 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1359 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1360 */ 1361 1362 #include <sys/types.h> 1363 #include <string.h> 1364 1365 size_t 1366 strnlen(const char *str, size_t maxlen) 1367 { 1368 const char *cp; 1369 1370 for (cp = str; maxlen != 0 && *cp != '\0'; cp++, maxlen--) 1371 ; 1372 1373 return (size_t)(cp - str); 1374 } 1375 #endif /* !HAVE_STRNLEN */ 1376 #if !HAVE_STRTONUM 1377 /* 1378 * Copyright (c) 2004 Ted Unangst and Todd Miller 1379 * All rights reserved. 1380 * 1381 * Permission to use, copy, modify, and distribute this software for any 1382 * purpose with or without fee is hereby granted, provided that the above 1383 * copyright notice and this permission notice appear in all copies. 1384 * 1385 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1386 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1387 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1388 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1389 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1390 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1391 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1392 */ 1393 1394 #include <errno.h> 1395 #include <limits.h> 1396 #include <stdlib.h> 1397 1398 #define INVALID 1 1399 #define TOOSMALL 2 1400 #define TOOLARGE 3 1401 1402 long long 1403 strtonum(const char *numstr, long long minval, long long maxval, 1404 const char **errstrp) 1405 { 1406 long long ll = 0; 1407 int error = 0; 1408 char *ep; 1409 struct errval { 1410 const char *errstr; 1411 int err; 1412 } ev[4] = { 1413 { NULL, 0 }, 1414 { "invalid", EINVAL }, 1415 { "too small", ERANGE }, 1416 { "too large", ERANGE }, 1417 }; 1418 1419 ev[0].err = errno; 1420 errno = 0; 1421 if (minval > maxval) { 1422 error = INVALID; 1423 } else { 1424 ll = strtoll(numstr, &ep, 10); 1425 if (numstr == ep || *ep != '\0') 1426 error = INVALID; 1427 else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval) 1428 error = TOOSMALL; 1429 else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval) 1430 error = TOOLARGE; 1431 } 1432 if (errstrp != NULL) 1433 *errstrp = ev[error].errstr; 1434 errno = ev[error].err; 1435 if (error) 1436 ll = 0; 1437 1438 return (ll); 1439 } 1440 #endif /* !HAVE_STRTONUM */