1 /*
2 * tlsdated.c - invoke tlsdate when necessary.
3 * Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 *
7 * We invoke tlsdate once at system startup, then we start trying to invoke
8 * tlsdate when a new network route appears. We try a few times after each route
9 * comes up. As soon as we get a successful tlsdate run, we save that timestamp
10 * to disk, then linger to wait for system shutdown. At system shutdown
11 * (indicated by us getting SIGTERM), we save our timestamp to disk.
12 */
13
14 #include "config.h"
15
16 #include <assert.h>
17 #include <errno.h>
18 #include <grp.h> /* setgroups */
19 #include <fcntl.h>
20 #include <limits.h>
21 #include <linux/rtc.h>
22 #include <stdarg.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/ioctl.h>
29 #include <sys/stat.h>
30 #include <sys/time.h>
31 #include <sys/wait.h>
32 #include <time.h>
33 #include <unistd.h>
34
35
36 #include <event2/event.h>
37
38 #include "src/conf.h"
39 #include "src/routeup.h"
40 #include "src/util.h"
41 #include "src/tlsdate.h"
42 #include "src/dbus.h"
43 #include "src/platform.h"
44
45
46 static const char kTlsdatedOpts[] = "hwrpt:d:T:D:c:a:lsvbm:j:f:x:Uu:g:G:";
47 const char *kCacheDir = DEFAULT_DAEMON_CACHEDIR;
48
49 int
is_sane_time(time_t ts)50 is_sane_time (time_t ts)
51 {
52 return ts > RECENT_COMPILE_DATE && ts < TLSDATED_MAX_DATE;
53 }
54
55 /*
56 * Load a time value out of the file named by path. Returns 0 if successful,
57 * -1 if not. The file contains the time in seconds since epoch in host byte
58 * order.
59 */
60 int
load_disk_timestamp(const char * path,time_t * t)61 load_disk_timestamp (const char *path, time_t * t)
62 {
63 int fd = platform->file_open (path, 0 /* RDONLY */, 1 /* CLOEXEC */);
64 time_t tmpt = 0;
65 if (fd < 0)
66 {
67 perror ("Can't open %s for reading", path);
68 return -1;
69 }
70 if (platform->file_read(fd, &tmpt, sizeof(tmpt)))
71 {
72 perror ("Can't read seconds from %s", path);
73 platform->file_close (fd);
74 return -1;
75 }
76 platform->file_close (fd);
77 if (!is_sane_time (tmpt))
78 {
79 error ("Disk timestamp is not sane: %ld", tmpt);
80 return -1;
81 }
82 *t = tmpt;
83 return 0;
84 }
85
86
87 void
usage(const char * progn)88 usage (const char *progn)
89 {
90 printf ("Usage: %s [flags...] [--] [tlsdate command...]\n", progn);
91 printf (" -w don't set hwclock\n");
92 printf (" -p dry run (don't really set time)\n");
93 printf (" -r use stdin instead of netlink for routes\n");
94 printf (" -t <n> try n times to synchronize the time\n");
95 printf (" -d <n> delay n seconds between tries\n");
96 printf (" -T <n> give subprocess n chances to exit\n");
97 printf (" -D <n> delay n seconds between wait attempts\n");
98 printf (" -c <path> set the cache directory\n");
99 printf (" -a <n> run at most every n seconds in steady state\n");
100 printf (" -m <n> run at most once every n seconds in steady state\n");
101 printf (" -j <n> add up to n seconds jitter to steady state checks\n");
102 printf (" -l don't load disk timestamps\n");
103 printf (" -s don't save disk timestamps\n");
104 printf (" -U don't use DBus if supported\n");
105 printf (" -u <user> user to change to\n");
106 printf (" -g <grp> group to change to\n");
107 printf (" -G <grps> comma-separated list of supplementary groups\n");
108 printf (" -v be verbose\n");
109 printf (" -b use verbose debugging\n");
110 printf (" -x <h> set proxy for subprocs to h\n");
111 printf (" -h this\n");
112 }
113
114 void
set_conf_defaults(struct opts * opts)115 set_conf_defaults (struct opts *opts)
116 {
117 static char *kDefaultArgv[] =
118 {
119 (char *) DEFAULT_TLSDATE, (char *) "-H", (char *) DEFAULT_HOST, NULL
120 };
121 opts->user = UNPRIV_USER;
122 opts->group = UNPRIV_GROUP;
123 opts->supp_groups = NULL;
124 opts->max_tries = MAX_TRIES;
125 opts->min_steady_state_interval = STEADY_STATE_INTERVAL;
126 opts->wait_between_tries = WAIT_BETWEEN_TRIES;
127 opts->subprocess_tries = SUBPROCESS_TRIES;
128 opts->subprocess_wait_between_tries = SUBPROCESS_WAIT_BETWEEN_TRIES;
129 opts->steady_state_interval = STEADY_STATE_INTERVAL;
130 opts->continuity_interval = CONTINUITY_INTERVAL;
131 opts->base_path = kCacheDir;
132 opts->base_argv = kDefaultArgv;
133 opts->argv = NULL;
134 opts->should_dbus = 1;
135 opts->should_sync_hwclock = DEFAULT_SYNC_HWCLOCK;
136 opts->should_load_disk = DEFAULT_LOAD_FROM_DISK;
137 opts->should_save_disk = DEFAULT_SAVE_TO_DISK;
138 opts->should_netlink = DEFAULT_USE_NETLINK;
139 opts->dry_run = DEFAULT_DRY_RUN;
140 opts->jitter = 0;
141 opts->conf_file = NULL;
142 opts->sources = NULL;
143 opts->cur_source = NULL;
144 opts->proxy = NULL;
145 opts->leap = 0;
146 }
147
148 void
parse_argv(struct opts * opts,int argc,char * argv[])149 parse_argv (struct opts *opts, int argc, char *argv[])
150 {
151 int opt;
152 while ((opt = getopt (argc, argv, kTlsdatedOpts)) != -1)
153 {
154 switch (opt)
155 {
156 case 'w':
157 opts->should_sync_hwclock = 0;
158 break;
159 case 'r':
160 opts->should_netlink = 0;
161 break;
162 case 'U':
163 opts->should_dbus = 0;
164 break;
165 case 'p':
166 opts->dry_run = 1;
167 break;
168 case 't':
169 opts->max_tries = atoi (optarg);
170 break;
171 case 'd':
172 opts->wait_between_tries = atoi (optarg);
173 break;
174 case 'T':
175 opts->subprocess_tries = atoi (optarg);
176 break;
177 case 'D':
178 opts->subprocess_wait_between_tries = atoi (optarg);
179 break;
180 case 'c':
181 opts->base_path = optarg;
182 break;
183 case 'a':
184 opts->steady_state_interval = atoi (optarg);
185 break;
186 case 'l':
187 opts->should_load_disk = 0;
188 break;
189 case 's':
190 opts->should_save_disk = 0;
191 break;
192 case 'v':
193 verbose = 1;
194 break;
195 case 'b':
196 verbose_debug = 1;
197 break;
198 case 'm':
199 opts->min_steady_state_interval = atoi (optarg);
200 break;
201 case 'j':
202 opts->jitter = atoi (optarg);
203 break;
204 case 'f':
205 opts->conf_file = optarg;
206 break;
207 case 'x':
208 opts->proxy = optarg;
209 break;
210 case 'u':
211 opts->user = optarg;
212 break;
213 case 'g':
214 opts->group = optarg;
215 break;
216 case 'G':
217 opts->supp_groups = optarg;
218 break;
219 case 'h':
220 default:
221 usage (argv[0]);
222 exit (1);
223 }
224 }
225 if (optind < argc)
226 opts->base_argv = argv + optind;
227 /* Validate arguments */
228 }
229
230 static
add_source_to_conf(struct opts * opts,char * host,char * port,char * proxy)231 void add_source_to_conf (struct opts *opts, char *host, char *port, char *proxy)
232 {
233 struct source *s;
234 struct source *source = (struct source *) calloc (1, sizeof *source);
235 if (!source)
236 fatal ("out of memory for source");
237 source->host = strdup (host);
238 if (!source->host)
239 fatal ("out of memory for host");
240 source->port = strdup (port);
241 if (!source->port)
242 fatal ("out of memory for port");
243 if (proxy)
244 {
245 source->proxy = strdup (proxy);
246 if (!source->proxy)
247 fatal ("out of memory for proxy");
248 }
249 if (!opts->sources)
250 {
251 opts->sources = source;
252 source->id = 0;
253 }
254 else
255 {
256 for (s = opts->sources; s->next; s = s->next)
257 ;
258 source->id = s->id + 1;
259 s->next = source;
260 }
261 }
262
263 static struct conf_entry *
parse_source(struct opts * opts,struct conf_entry * conf)264 parse_source (struct opts *opts, struct conf_entry *conf)
265 {
266 char *host = NULL;
267 char *port = NULL;
268 char *proxy = NULL;
269 /* a source entry:
270 * source
271 * host <host>
272 * port <port>
273 * [proxy <proxy>]
274 * end
275 */
276 assert (!strcmp (conf->key, "source"));
277 conf = conf->next;
278 while (conf && strcmp (conf->key, "end"))
279 {
280 if (!strcmp (conf->key, "host"))
281 host = conf->value;
282 else if (!strcmp (conf->key, "port"))
283 port = conf->value;
284 else if (!strcmp (conf->key, "proxy"))
285 proxy = conf->value;
286 else
287 fatal ("malformed config: '%s' in source stanza", conf->key);
288 conf = conf->next;
289 }
290 if (!conf)
291 fatal ("unclosed source stanza");
292 if (!host || !port)
293 fatal ("incomplete source stanza (needs host, port)");
294 add_source_to_conf (opts, host, port, proxy);
295 return conf;
296 }
297
298 void
load_conf(struct opts * opts)299 load_conf (struct opts *opts)
300 {
301 FILE *f;
302 struct conf_entry *conf, *e;
303 char *conf_file = opts->conf_file;
304 if (!opts->conf_file)
305 conf_file = (char *) DEFAULT_CONF_FILE;
306 f = fopen (conf_file, "r");
307 if (!f)
308 {
309 if (opts->conf_file)
310 {
311 pfatal ("can't open conf file '%s'", opts->conf_file);
312 }
313 else
314 {
315 pinfo ("can't open conf file '%s'", conf_file);
316 return;
317 }
318 }
319 conf = conf_parse (f);
320 if (!conf)
321 pfatal ("can't parse config file");
322
323 for (e = conf; e; e = e->next)
324 {
325 if (!strcmp (e->key, "max-tries") && e->value)
326 {
327 opts->max_tries = atoi (e->value);
328 }
329 else if (!strcmp (e->key, "min-steady-state-interval") && e->value)
330 {
331 opts->min_steady_state_interval = atoi (e->value);
332 }
333 else if (!strcmp (e->key, "wait-between-tries") && e->value)
334 {
335 opts->wait_between_tries = atoi (e->value);
336 }
337 else if (!strcmp (e->key, "subprocess-tries") && e->value)
338 {
339 opts->subprocess_tries = atoi (e->value);
340 }
341 else if (!strcmp (e->key, "subprocess-wait-between-tries") && e->value)
342 {
343 opts->subprocess_wait_between_tries = atoi (e->value);
344 }
345 else if (!strcmp (e->key, "steady-state-interval") && e->value)
346 {
347 opts->steady_state_interval = atoi (e->value);
348 }
349 else if (!strcmp (e->key, "base-path") && e->value)
350 {
351 opts->base_path = strdup (e->value);
352 if (!opts->base_path)
353 fatal ("out of memory for base path");
354 }
355 else if (!strcmp (e->key, "should-sync-hwclock"))
356 {
357 opts->should_sync_hwclock = e->value ? !strcmp (e->value, "yes") : 1;
358 }
359 else if (!strcmp (e->key, "should-load-disk"))
360 {
361 opts->should_load_disk = e->value ? !strcmp (e->value, "yes") : 1;
362 }
363 else if (!strcmp (e->key, "should-save-disk"))
364 {
365 opts->should_save_disk = e->value ? !strcmp (e->value, "yes") : 1;
366 }
367 else if (!strcmp (e->key, "should-netlink"))
368 {
369 opts->should_netlink = e->value ? !strcmp (e->value, "yes") : 1;
370 }
371 else if (!strcmp (e->key, "dry-run"))
372 {
373 opts->dry_run = e->value ? !strcmp (e->value, "yes") : 1;
374 }
375 else if (!strcmp (e->key, "jitter") && e->value)
376 {
377 opts->jitter = atoi (e->value);
378 }
379 else if (!strcmp (e->key, "verbose"))
380 {
381 verbose = e->value ? !strcmp (e->value, "yes") : 1;
382 }
383 else if (!strcmp (e->key, "source"))
384 {
385 e = parse_source (opts, e);
386 }
387 else if (!strcmp (e->key, "leap"))
388 {
389 opts->leap = e->value ? !strcmp (e->value, "yes") : 1;
390 }
391 }
392 }
393
394 void
check_conf(struct state * state)395 check_conf (struct state *state)
396 {
397 struct opts *opts = &state->opts;
398 if (!opts->max_tries)
399 fatal ("-t argument must be nonzero");
400 if (!opts->wait_between_tries)
401 fatal ("-d argument must be nonzero");
402 if (!opts->steady_state_interval)
403 fatal ("-a argument must be nonzero");
404 int ret = snprintf (state->timestamp_path, sizeof (state->timestamp_path),
405 "%s/timestamp", opts->base_path);
406 if (ret < 0 || ((size_t) ret) >= sizeof (state->timestamp_path))
407 fatal ("supplied base path is too long: '%s'", opts->base_path);
408 if (opts->jitter >= opts->steady_state_interval)
409 fatal ("jitter must be less than steady state interval (%d >= %d)",
410 opts->jitter, opts->steady_state_interval);
411 }
412
413 int
cleanup_main(struct state * state)414 cleanup_main (struct state *state)
415 {
416 int i;
417 for (i = 0; i < E_MAX; ++i)
418 {
419 struct event *e = state->events[i];
420 if (e)
421 {
422 int fd = event_get_fd (e);
423 if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL))
424 close (fd);
425 event_free (e);
426 }
427 }
428 /* The other half was closed above. */
429 platform->file_close (state->tlsdate_monitor_fd);
430 if (state->tlsdate_pid)
431 {
432 platform->process_signal (state->tlsdate_pid, SIGKILL);
433 platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */);
434 }
435 /* Best effort to tear it down if it is still alive. */
436 close(state->setter_notify_fd);
437 close(state->setter_save_fd);
438 if (state->setter_pid)
439 {
440 platform->process_signal (state->setter_pid, SIGKILL);
441 platform->process_wait (state->setter_pid, NULL, 0 /* !forever */);
442 }
443 /* TODO(wad) Add dbus_cleanup() */
444 if (state->base)
445 event_base_free (state->base);
446 memset(state, 0, sizeof(*state));
447 info ("tlsdated clean up finished; exiting!");
448 terminate_syslog ();
449 return 0;
450 }
451
452 #ifdef TLSDATED_MAIN
453 static const char **
parse_supp_groups(char * arg)454 parse_supp_groups (char *arg)
455 {
456 size_t i;
457 char *scan;
458 const char **supp_groups;
459
460 for (i = 1, scan = arg; (scan = strchr (scan, ',')); i++, scan++) ;
461 supp_groups = (const char **) calloc (i + 1, sizeof (const char *));
462 if (!supp_groups)
463 die ("Failed to allocate memory for supplementary group names\n");
464 for (i = 0; (supp_groups[i] = strsep (&arg, ",")); i++) ;
465 return supp_groups;
466 }
467
468 int API
main(int argc,char * argv[],char * envp[])469 main (int argc, char *argv[], char *envp[])
470 {
471 const char **supp_groups = NULL;
472
473 initalize_syslog ();
474 struct state state;
475 /* TODO(wad) EVENT_BASE_FLAG_PRECISE_TIMER | EVENT_BASE_FLAG_PRECISE_TIMER */
476 struct event_base *base = event_base_new();
477 if (!base)
478 {
479 fatal ("could not allocated new event base");
480 }
481 /* Add three priority levels:
482 * 0 - time saving. Must be done before any other events are handled.
483 * 1 - network synchronization events
484 * 2 - any other events (wake, platform, etc)
485 */
486 event_base_priority_init (base, MAX_EVENT_PRIORITIES);
487 memset (&state, 0, sizeof (state));
488 set_conf_defaults (&state.opts);
489 parse_argv (&state.opts, argc, argv);
490 check_conf (&state);
491 load_conf (&state.opts);
492 check_conf (&state);
493 if (!state.opts.sources)
494 add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY);
495 state.base = base;
496 state.envp = envp;
497 state.backoff = state.opts.wait_between_tries;
498 /* TODO(wad) move this into setup_time_setter */
499 /* grab a handle to /dev/rtc for time-setter. */
500 if (state.opts.should_sync_hwclock &&
501 platform->rtc_open(&state.hwclock))
502 {
503 pinfo ("can't open hwclock fd");
504 state.opts.should_sync_hwclock = 0;
505 }
506 /* install the SIGCHLD handler for the setter and tlsdate */
507 if (setup_sigchld_event (&state, 1))
508 {
509 error ("Failed to setup SIGCHLD event");
510 goto out;
511 }
512 /* fork off the privileged helper */
513 verb ("spawning time setting helper . . .");
514 if (setup_time_setter (&state))
515 {
516 error ("could not fork privileged coprocess");
517 goto out;
518 }
519 /* release the hwclock now that the time-setter is running. */
520 if (state.opts.should_sync_hwclock)
521 {
522 platform->rtc_close (&state.hwclock);
523 }
524 /* drop privileges before touching any untrusted data */
525 if (state.opts.supp_groups)
526 supp_groups = parse_supp_groups (state.opts.supp_groups);
527 drop_privs_to (state.opts.user, state.opts.group, supp_groups);
528 free (supp_groups);
529 /* register a signal handler to save time at shutdown */
530 if (state.opts.should_save_disk)
531 {
532 struct event *event = event_new (base, SIGTERM, EV_SIGNAL|EV_PERSIST,
533 action_sigterm, &state);
534 if (!event)
535 fatal ("Failed to create SIGTERM event");
536 event_priority_set (event, PRI_SAVE);
537 event_add (event, NULL);
538 }
539 if (state.opts.should_dbus && init_dbus (&state))
540 {
541 error ("Failed to initialize DBus");
542 goto out;
543 }
544 /* Register the tlsdate event before any listeners could show up. */
545 state.events[E_TLSDATE] = event_new (base, -1, EV_TIMEOUT,
546 action_run_tlsdate, &state);
547 if (!state.events[E_TLSDATE])
548 {
549 error ("Failed to create tlsdate event");
550 goto out;
551 }
552 event_priority_set (state.events[E_TLSDATE], PRI_NET);
553 /* The timeout and fd will be filled in per-call. */
554 if (setup_tlsdate_status (&state))
555 {
556 error ("Failed to create tlsdate status event");
557 goto out;
558 }
559 /* TODO(wad) Could use a timeout on this to catch setter death? */
560 /* EV_READ is for truncation/EPIPE notification */
561 state.events[E_SAVE] = event_new (base, state.setter_save_fd,
562 EV_READ|EV_WRITE, action_sync_and_save,
563 &state);
564 if (!state.events[E_SAVE])
565 {
566 error ("Failed to create sync & save event");
567 goto out;
568 }
569 event_priority_set (state.events[E_SAVE], PRI_SAVE);
570 /* Start by grabbing the system time. */
571 state.last_sync_type = SYNC_TYPE_RTC;
572 state.last_time = time (NULL);
573 /* If possible, grab disk time and check the two. */
574 if (state.opts.should_load_disk)
575 {
576 time_t disk_time = state.last_time;
577 if (!load_disk_timestamp (state.timestamp_path, &disk_time))
578 {
579 verb ("disk timestamp available: yes (%ld)", disk_time);
580 if (!is_sane_time (state.last_time) ||
581 state.last_time < disk_time)
582 {
583 state.last_sync_type = SYNC_TYPE_DISK;
584 state.last_time = disk_time;
585 }
586 }
587 else
588 {
589 verb ("disk timestamp available: no");
590 }
591 }
592 if (!is_sane_time (state.last_time))
593 {
594 state.last_sync_type = SYNC_TYPE_BUILD;
595 state.last_time = RECENT_COMPILE_DATE + 1;
596 }
597 /* Save and announce the initial time source. */
598 trigger_event (&state, E_SAVE, -1);
599 verb ("tlsdated parasitic time synchronization initialized");
600 info ("initial time sync type: %s", sync_type_str (state.last_sync_type));
601 /* Initialize platform specific loop behavior */
602 if (platform_init_cros (&state))
603 {
604 error ("Failed to initialize platform code");
605 goto out;
606 }
607 if (setup_event_route_up (&state))
608 {
609 error ("Failed to setup route up monitoring");
610 goto out;
611 }
612 if (setup_event_timer_sync (&state))
613 {
614 error ("Failed to setup a timer event");
615 goto out;
616 }
617 if (setup_event_timer_continuity (&state))
618 {
619 error ("Failed to setup continuity timer");
620 goto out;
621 }
622 /* Add a forced sync event to the event list. */
623 action_kickoff_time_sync (-1, EV_TIMEOUT, &state);
624 verb ("Entering dispatch . . .");
625 event_base_dispatch (base);
626 verb ("tlsdated event dispatch terminating gracefully");
627 out:
628 return cleanup_main (&state);
629 }
630 #endif /* !TLSDATED_MAIN */
631