1 /* $OpenBSD: ntp.c,v 1.37 2023/11/12 18:53:22 otto Exp $ */ 2 3 /* 4 * Copyright (c) 1996, 1997 by N.M. Maclaren. All rights reserved. 5 * Copyright (c) 1996, 1997 by University of Cambridge. All rights reserved. 6 * Copyright (c) 2002 by Thorsten "mirabile" Glaser. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the author nor the university may be used to 17 * endorse or promote products derived from this software without 18 * specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/socket.h> 33 #include <sys/time.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 37 #include <ctype.h> 38 #include <err.h> 39 #include <errno.h> 40 #include <fcntl.h> 41 #include <float.h> 42 #include <limits.h> 43 #include <math.h> 44 #include <netdb.h> 45 #include <stdint.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <time.h> 50 #include <poll.h> 51 #include <unistd.h> 52 53 #include "ntpleaps.h" 54 55 /* 56 * NTP definitions. Note that these assume 8-bit bytes - sigh. There 57 * is little point in parameterising everything, as it is neither 58 * feasible nor useful. It would be very useful if more fields could 59 * be defined as unspecified. The NTP packet-handling routines 60 * contain a lot of extra assumptions. 61 */ 62 63 #define JAN_1970 2208988800.0 /* 1970 - 1900 in seconds */ 64 #define NTP_SCALE 4294967296.0 /* 2^32, of course! */ 65 66 #define NTP_MODE_CLIENT 3 /* NTP client mode */ 67 #define NTP_MODE_SERVER 4 /* NTP server mode */ 68 #define NTP_VERSION 4 /* The current version */ 69 #define NTP_VERSION_MIN 1 /* The minimum valid version */ 70 #define NTP_VERSION_MAX 4 /* The maximum valid version */ 71 #define NTP_STRATUM_MAX 14 /* The maximum valid stratum */ 72 #define NTP_INSANITY 3600.0 /* Errors beyond this are hopeless */ 73 74 #define NTP_PACKET_MIN 48 /* Without authentication */ 75 #define NTP_PACKET_MAX 68 /* With authentication (ignored) */ 76 77 #define NTP_DISP_FIELD 8 /* Offset of dispersion field */ 78 #define NTP_REFERENCE 16 /* Offset of reference timestamp */ 79 #define NTP_ORIGINATE 24 /* Offset of originate timestamp */ 80 #define NTP_RECEIVE 32 /* Offset of receive timestamp */ 81 #define NTP_TRANSMIT 40 /* Offset of transmit timestamp */ 82 83 #define STATUS_NOWARNING 0 /* No Leap Indicator */ 84 #define STATUS_LEAPHIGH 1 /* Last Minute Has 61 Seconds */ 85 #define STATUS_LEAPLOW 2 /* Last Minute Has 59 Seconds */ 86 #define STATUS_ALARM 3 /* Server Clock Not Synchronized */ 87 88 #define MAX_QUERIES 25 89 #define MAX_DELAY 15 90 91 #define MILLION_L 1000000l /* For conversion to/from timeval */ 92 #define MILLION_D 1.0e6 /* Must be equal to MILLION_L */ 93 94 /* 95 * The era we're in if we have no reason to assume otherwise. 96 * If unpack_ntp() sees a small offset the era is is assumed to be 97 * NTP_ERA + 1. 98 * Once the actual year is well into era 1, (after 2036) define NTP_ERA to 1 99 * and adapt (disable) the increments in unpack_ntp(). 100 * Once more than half of era 1 has elapsed (after 2104), re-inroduce the test 101 * to move to era 2 if offset is small, repeat for each half era. 102 */ 103 #define NTP_ERA 0 104 105 #define SECS_IN_ERA (UINT32_MAX + 1ULL) 106 107 108 struct ntp_data { 109 u_char status; 110 u_char version; 111 u_char mode; 112 u_char stratum; 113 double receive; 114 double transmit; 115 double current; 116 u_int64_t recvck; 117 118 /* Local State */ 119 double originate; 120 u_int64_t xmitck; 121 }; 122 123 void ntp_client(const char *, int, struct timeval *, struct timeval *, int); 124 int sync_ntp(int, const struct sockaddr *, double *, double *); 125 int write_packet(int, struct ntp_data *); 126 int read_packet(int, struct ntp_data *, double *, double *); 127 void unpack_ntp(struct ntp_data *, u_char *); 128 double current_time(double); 129 void create_timeval(double, struct timeval *, struct timeval *); 130 131 #ifdef DEBUG 132 void print_packet(const struct ntp_data *); 133 #endif 134 135 int corrleaps; 136 137 void 138 ntp_client(const char *hostname, int family, struct timeval *new, 139 struct timeval *adjust, int leapflag) 140 { 141 struct addrinfo hints, *res0, *res; 142 double offset, error; 143 int accept = 0, ret, s, ierror; 144 145 memset(&hints, 0, sizeof(hints)); 146 hints.ai_family = family; 147 hints.ai_socktype = SOCK_DGRAM; 148 ierror = getaddrinfo(hostname, "ntp", &hints, &res0); 149 if (ierror) { 150 errx(1, "%s: %s", hostname, gai_strerror(ierror)); 151 /*NOTREACHED*/ 152 } 153 154 if (pledge("stdio inet", NULL) == -1) 155 err(1, "pledge"); 156 157 corrleaps = leapflag; 158 if (corrleaps) 159 ntpleaps_init(); 160 161 s = -1; 162 for (res = res0; res; res = res->ai_next) { 163 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 164 if (s == -1) 165 continue; 166 167 ret = sync_ntp(s, res->ai_addr, &offset, &error); 168 if (ret < 0) { 169 #ifdef DEBUG 170 fprintf(stderr, "try the next address\n"); 171 #endif 172 close(s); 173 s = -1; 174 continue; 175 } 176 177 accept++; 178 break; 179 } 180 freeaddrinfo(res0); 181 182 #ifdef DEBUG 183 fprintf(stderr, "Correction: %.6f +/- %.6f\n", offset, error); 184 #endif 185 186 if (accept < 1) 187 errx(1, "Unable to get a reasonable time estimate"); 188 189 create_timeval(offset, new, adjust); 190 } 191 192 int 193 sync_ntp(int fd, const struct sockaddr *peer, double *offset, double *error) 194 { 195 int accepts = 0, rejects = 0; 196 int delay = MAX_DELAY, ret; 197 double deadline; 198 double a, b, x, y; 199 double minerr = 0.1; /* Maximum ignorable variation */ 200 struct ntp_data data; 201 202 deadline = current_time(JAN_1970) + delay; 203 *offset = 0.0; 204 *error = NTP_INSANITY; 205 206 if (connect(fd, peer, SA_LEN(peer)) == -1) { 207 warn("Failed to connect to server"); 208 return (-1); 209 } 210 211 while (accepts < MAX_QUERIES) { 212 memset(&data, 0, sizeof(data)); 213 214 if (current_time(JAN_1970) > deadline) { 215 warnx("Not enough valid responses received in time"); 216 return (-1); 217 } 218 219 if (write_packet(fd, &data) < 0) 220 return (-1); 221 222 ret = read_packet(fd, &data, &x, &y); 223 224 if (ret < 0) 225 return (-1); 226 else if (ret > 0) { 227 #ifdef DEBUG 228 print_packet(&data); 229 #endif 230 231 if (++rejects > MAX_QUERIES) { 232 warnx("Too many bad or lost packets"); 233 return (-1); 234 } else 235 continue; 236 } else 237 ++accepts; 238 239 #ifdef DEBUG 240 fprintf(stderr, "Offset: %.6f +/- %.6f\n", x, y); 241 #endif 242 243 if ((a = x - *offset) < 0.0) 244 a = -a; 245 if (accepts <= 1) 246 a = 0.0; 247 b = *error + y; 248 if (y < *error) { 249 *offset = x; 250 *error = y; 251 } 252 253 #ifdef DEBUG 254 fprintf(stderr, "Best: %.6f +/- %.6f\n", *offset, *error); 255 #endif 256 257 if (a > b) { 258 warnx("Inconsistent times received from NTP server"); 259 return (-1); 260 } 261 262 if ((data.status & STATUS_ALARM) == STATUS_ALARM) { 263 warnx("Ignoring NTP server with alarm flag set"); 264 return (-1); 265 } 266 267 if (*error <= minerr) 268 break; 269 } 270 271 return (accepts); 272 } 273 274 /* Send out NTP packet. */ 275 int 276 write_packet(int fd, struct ntp_data *data) 277 { 278 u_char packet[NTP_PACKET_MIN]; 279 ssize_t length; 280 281 memset(packet, 0, sizeof(packet)); 282 283 packet[0] = (NTP_VERSION << 3) | (NTP_MODE_CLIENT); 284 285 arc4random_buf(&data->xmitck, sizeof(data->xmitck)); 286 287 /* 288 * Send out a random 64-bit number as our transmit time. The NTP 289 * server will copy said number into the originate field on the 290 * response that it sends us. This is totally legal per the SNTP spec. 291 * 292 * The impact of this is two fold: we no longer send out the current 293 * system time for the world to see (which may aid an attacker), and 294 * it gives us a (not very secure) way of knowing that we're not 295 * getting spoofed by an attacker that can't capture our traffic 296 * but can spoof packets from the NTP server we're communicating with. 297 * 298 * No endian concerns here. Since we're running as a strict 299 * unicast client, we don't have to worry about anyone else finding 300 * the transmit field intelligible. 301 */ 302 303 bcopy(&data->xmitck, (packet + NTP_TRANSMIT), sizeof(data->xmitck)); 304 305 data->originate = current_time(JAN_1970); 306 307 length = write(fd, packet, sizeof(packet)); 308 309 if (length != sizeof(packet)) { 310 warn("Unable to send NTP packet to server"); 311 return (-1); 312 } 313 314 return (0); 315 } 316 317 /* 318 * Check the packet and work out the offset and optionally the error. 319 * Note that this contains more checking than xntp does. Return 0 for 320 * success, 1 for failure. Note that it must not change its arguments 321 * if it fails. 322 */ 323 int 324 read_packet(int fd, struct ntp_data *data, double *off, double *error) 325 { 326 u_char receive[NTP_PACKET_MAX]; 327 struct pollfd pfd[1]; 328 double x, y; 329 int length, r; 330 331 pfd[0].fd = fd; 332 pfd[0].events = POLLIN; 333 334 retry: 335 r = poll(pfd, 1, 1000 * MAX_DELAY / MAX_QUERIES); 336 if (r == -1) { 337 if (errno == EINTR) 338 goto retry; 339 warn("select"); 340 return (r); 341 } 342 343 if (r != 1) 344 return (1); 345 if ((pfd[0].revents & POLLIN) == 0) 346 return (1); 347 348 length = read(fd, receive, NTP_PACKET_MAX); 349 if (length == -1) { 350 warn("Unable to receive NTP packet from server"); 351 return (-1); 352 } 353 354 if (length < NTP_PACKET_MIN || length > NTP_PACKET_MAX) { 355 warnx("Invalid NTP packet size, packet rejected"); 356 return (1); 357 } 358 359 unpack_ntp(data, receive); 360 361 if (data->recvck != data->xmitck) { 362 warnx("Invalid cookie received, packet rejected"); 363 return (1); 364 } 365 366 if (data->version < NTP_VERSION_MIN || 367 data->version > NTP_VERSION_MAX) { 368 warnx("Received NTP version %u, need %u or lower", 369 data->version, NTP_VERSION); 370 return (1); 371 } 372 373 if (data->mode != NTP_MODE_SERVER) { 374 warnx("Invalid NTP server mode, packet rejected"); 375 return (1); 376 } 377 378 if (data->stratum > NTP_STRATUM_MAX) { 379 warnx("Invalid stratum received, packet rejected"); 380 return (1); 381 } 382 383 if (data->transmit == 0.0) { 384 warnx("Server clock invalid, packet rejected"); 385 return (1); 386 } 387 388 x = data->receive - data->originate; 389 y = data->transmit - data->current; 390 391 *off = (x + y) / 2; 392 *error = x - y; 393 394 x = (data->current - data->originate) / 2; 395 396 if (x > *error) 397 *error = x; 398 399 return (0); 400 } 401 402 /* 403 * Unpack the essential data from an NTP packet, bypassing struct 404 * layout and endian problems. Note that it ignores fields irrelevant 405 * to SNTP. 406 */ 407 void 408 unpack_ntp(struct ntp_data *data, u_char *packet) 409 { 410 int i, era; 411 double d; 412 413 data->current = current_time(JAN_1970); 414 415 data->status = (packet[0] >> 6); 416 data->version = (packet[0] >> 3) & 0x07; 417 data->mode = packet[0] & 0x07; 418 data->stratum = packet[1]; 419 420 for (i = 0, d = 0.0; i < 8; ++i) 421 d = 256.0*d+packet[NTP_RECEIVE+i]; 422 423 era = NTP_ERA; 424 if (packet[NTP_RECEIVE] <= 127) 425 era++; 426 data->receive = d / NTP_SCALE; 427 data->receive += era * SECS_IN_ERA; 428 429 for (i = 0, d = 0.0; i < 8; ++i) 430 d = 256.0*d+packet[NTP_TRANSMIT+i]; 431 432 era = NTP_ERA; 433 if (packet[NTP_TRANSMIT] <= 127) 434 era++; 435 data->transmit = d / NTP_SCALE; 436 data->transmit += era * SECS_IN_ERA; 437 438 /* See write_packet for why this isn't an endian problem. */ 439 bcopy((packet + NTP_ORIGINATE), &data->recvck, sizeof(data->recvck)); 440 } 441 442 /* 443 * Get the current UTC time in seconds since the Epoch plus an offset 444 * (usually the time from the beginning of the century to the Epoch) 445 */ 446 double 447 current_time(double offset) 448 { 449 struct timeval current; 450 u_int64_t t; 451 452 if (gettimeofday(¤t, NULL)) 453 err(1, "Could not get local time of day"); 454 455 /* 456 * At this point, current has the current TAI time. 457 * Now subtract leap seconds to set the posix tick. 458 */ 459 460 t = SEC_TO_TAI64(current.tv_sec); 461 if (corrleaps) 462 ntpleaps_sub(&t); 463 464 return (offset + TAI64_TO_SEC(t) + 1.0e-6 * current.tv_usec); 465 } 466 467 /* 468 * Change offset into current UTC time. This is portable, even if 469 * struct timeval uses an unsigned long for tv_sec. 470 */ 471 void 472 create_timeval(double difference, struct timeval *new, struct timeval *adjust) 473 { 474 struct timeval old; 475 long long n; 476 477 /* Start by converting to timeval format. Note that we have to 478 * cater for negative, unsigned values. */ 479 if ((n = (long long) difference) > difference) 480 --n; 481 adjust->tv_sec = n; 482 adjust->tv_usec = (long) (MILLION_D * (difference-n)); 483 errno = 0; 484 if (gettimeofday(&old, NULL)) 485 err(1, "Could not get local time of day"); 486 new->tv_sec = old.tv_sec + adjust->tv_sec; 487 new->tv_usec = (n = (long) old.tv_usec + (long) adjust->tv_usec); 488 489 if (n < 0) { 490 new->tv_usec += MILLION_L; 491 --new->tv_sec; 492 } else if (n >= MILLION_L) { 493 new->tv_usec -= MILLION_L; 494 ++new->tv_sec; 495 } 496 } 497 498 #ifdef DEBUG 499 void 500 print_packet(const struct ntp_data *data) 501 { 502 printf("status: %u\n", data->status); 503 printf("version: %u\n", data->version); 504 printf("mode: %u\n", data->mode); 505 printf("stratum: %u\n", data->stratum); 506 printf("originate: %f\n", data->originate); 507 printf("receive: %f\n", data->receive); 508 printf("transmit: %f\n", data->transmit); 509 printf("current: %f\n", data->current); 510 printf("xmitck: 0x%0llX\n", data->xmitck); 511 printf("recvck: 0x%0llX\n", data->recvck); 512 }; 513 #endif 514