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