16fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones/*
26fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * tlsdated.c - invoke tlsdate when necessary.
36fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * Copyright (c) 2012 The Chromium Authors. All rights reserved.
46fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * Use of this source code is governed by a BSD-style license that can be
56fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * found in the LICENSE file.
66fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones *
76fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * We invoke tlsdate once at system startup, then we start trying to invoke
86fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * tlsdate when a new network route appears. We try a few times after each route
96fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * comes up. As soon as we get a successful tlsdate run, we save that timestamp
106fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * to disk, then linger to wait for system shutdown. At system shutdown
116fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * (indicated by us getting SIGTERM), we save our timestamp to disk.
126fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones */
136fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
14b12abad3a804915ed94dd630bef04317feadd265Brian Aker#include "config.h"
15b12abad3a804915ed94dd630bef04317feadd265Brian Aker
166fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <assert.h>
176fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <errno.h>
18c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#include <grp.h> /* setgroups */
196fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <fcntl.h>
206fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <limits.h>
216fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <linux/rtc.h>
226fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <stdarg.h>
23c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#include <stdbool.h>
246fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <stdio.h>
256fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <stdint.h>
266fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <stdlib.h>
276fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <string.h>
286fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <sys/ioctl.h>
296fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <sys/stat.h>
306fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <sys/time.h>
316fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <sys/wait.h>
326fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <time.h>
336fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#include <unistd.h>
346fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
352d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry
36c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#include <event2/event.h>
37385386d927176a47bc71b7efaf51fb7806f72d80Paul Bakker
38677a136165e23dccf2912fda529809d1a59bd428elly#include "src/conf.h"
39b12abad3a804915ed94dd630bef04317feadd265Brian Aker#include "src/routeup.h"
40b12abad3a804915ed94dd630bef04317feadd265Brian Aker#include "src/util.h"
412efca57f2b02922aa50648d11b1a90559d863612Jacob Appelbaum#include "src/tlsdate.h"
42c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#include "src/dbus.h"
43c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#include "src/platform.h"
446fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
45aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold
46aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnoldstatic const char kTlsdatedOpts[] = "hwrpt:d:T:D:c:a:lsvbm:j:f:x:Uu:g:G:";
472efca57f2b02922aa50648d11b1a90559d863612Jacob Appelbaumconst char *kCacheDir = DEFAULT_DAEMON_CACHEDIR;
486fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
493abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesint
503abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesis_sane_time (time_t ts)
516fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{
523abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  return ts > RECENT_COMPILE_DATE && ts < TLSDATED_MAX_DATE;
536fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones}
546fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
556fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones/*
566fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * Load a time value out of the file named by path. Returns 0 if successful,
576fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * -1 if not. The file contains the time in seconds since epoch in host byte
586fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * order.
596fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones */
603abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesint
613abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesload_disk_timestamp (const char *path, time_t * t)
626fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{
639c331bf201909fb5a85725202eee872d4323e12dWill Drewry  int fd = platform->file_open (path, 0 /* RDONLY */, 1 /* CLOEXEC */);
649c331bf201909fb5a85725202eee872d4323e12dWill Drewry  time_t tmpt = 0;
653abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  if (fd < 0)
663abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    {
673abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      perror ("Can't open %s for reading", path);
683abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      return -1;
693abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    }
709c331bf201909fb5a85725202eee872d4323e12dWill Drewry  if (platform->file_read(fd, &tmpt, sizeof(tmpt)))
71385386d927176a47bc71b7efaf51fb7806f72d80Paul Bakker    {
723abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      perror ("Can't read seconds from %s", path);
739c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->file_close (fd);
743abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      return -1;
75385386d927176a47bc71b7efaf51fb7806f72d80Paul Bakker    }
769c331bf201909fb5a85725202eee872d4323e12dWill Drewry  platform->file_close (fd);
773abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  if (!is_sane_time (tmpt))
783abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    {
79c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Disk timestamp is not sane: %ld", tmpt);
803abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      return -1;
813abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    }
823abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  *t = tmpt;
833abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  return 0;
846fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones}
856fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
86aa04c0126a590fc9646d491151bcbfeed34ba693elly
87aa04c0126a590fc9646d491151bcbfeed34ba693ellyvoid
883abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesusage (const char *progn)
896fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{
903abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("Usage: %s [flags...] [--] [tlsdate command...]\n", progn);
913abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -w        don't set hwclock\n");
923abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -p        dry run (don't really set time)\n");
933abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -r        use stdin instead of netlink for routes\n");
9447313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry  printf ("  -t <n>    try n times to synchronize the time\n");
953abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -d <n>    delay n seconds between tries\n");
963abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -T <n>    give subprocess n chances to exit\n");
973abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -D <n>    delay n seconds between wait attempts\n");
983abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -c <path> set the cache directory\n");
993abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -a <n>    run at most every n seconds in steady state\n");
100f44f6232679fabdb5d3486b1691e6253c3a6a8abElly Fong-Jones  printf ("  -m <n>    run at most once every n seconds in steady state\n");
101ccd12459a1abbc9825c298a5ac96a4cb84998985elly  printf ("  -j <n>    add up to n seconds jitter to steady state checks\n");
1023abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -l        don't load disk timestamps\n");
1033abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -s        don't save disk timestamps\n");
1047daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry  printf ("  -U        don't use DBus if supported\n");
105c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  printf ("  -u <user> user to change to\n");
106c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  printf ("  -g <grp>  group to change to\n");
107aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  printf ("  -G <grps> comma-separated list of supplementary groups\n");
1083abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -v        be verbose\n");
10947313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry  printf ("  -b        use verbose debugging\n");
110254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly  printf ("  -x <h>    set proxy for subprocs to h\n");
1113abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  printf ("  -h        this\n");
1126fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones}
1136fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones
114677a136165e23dccf2912fda529809d1a59bd428ellyvoid
115c45952f88c568046a02bc0aea793008d8bb37755Will Drewryset_conf_defaults (struct opts *opts)
1166fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{
117c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  static char *kDefaultArgv[] =
118c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  {
1195b0ee57271eab109f103b42a326fc5b126e3bbdaJacob Appelbaum    (char *) DEFAULT_TLSDATE, (char *) "-H", (char *) DEFAULT_HOST, NULL
1203abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  };
121c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  opts->user = UNPRIV_USER;
122c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  opts->group = UNPRIV_GROUP;
123aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  opts->supp_groups = NULL;
124677a136165e23dccf2912fda529809d1a59bd428elly  opts->max_tries = MAX_TRIES;
125677a136165e23dccf2912fda529809d1a59bd428elly  opts->min_steady_state_interval = STEADY_STATE_INTERVAL;
126677a136165e23dccf2912fda529809d1a59bd428elly  opts->wait_between_tries = WAIT_BETWEEN_TRIES;
127677a136165e23dccf2912fda529809d1a59bd428elly  opts->subprocess_tries = SUBPROCESS_TRIES;
128677a136165e23dccf2912fda529809d1a59bd428elly  opts->subprocess_wait_between_tries = SUBPROCESS_WAIT_BETWEEN_TRIES;
129677a136165e23dccf2912fda529809d1a59bd428elly  opts->steady_state_interval = STEADY_STATE_INTERVAL;
130c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  opts->continuity_interval = CONTINUITY_INTERVAL;
131677a136165e23dccf2912fda529809d1a59bd428elly  opts->base_path = kCacheDir;
1320e35d0568fb679664719bbb83ab6b7319c018c85elly  opts->base_argv = kDefaultArgv;
1330e35d0568fb679664719bbb83ab6b7319c018c85elly  opts->argv = NULL;
1347daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry  opts->should_dbus = 1;
135677a136165e23dccf2912fda529809d1a59bd428elly  opts->should_sync_hwclock = DEFAULT_SYNC_HWCLOCK;
136677a136165e23dccf2912fda529809d1a59bd428elly  opts->should_load_disk = DEFAULT_LOAD_FROM_DISK;
137677a136165e23dccf2912fda529809d1a59bd428elly  opts->should_save_disk = DEFAULT_SAVE_TO_DISK;
138677a136165e23dccf2912fda529809d1a59bd428elly  opts->should_netlink = DEFAULT_USE_NETLINK;
139677a136165e23dccf2912fda529809d1a59bd428elly  opts->dry_run = DEFAULT_DRY_RUN;
140677a136165e23dccf2912fda529809d1a59bd428elly  opts->jitter = 0;
141677a136165e23dccf2912fda529809d1a59bd428elly  opts->conf_file = NULL;
1420e35d0568fb679664719bbb83ab6b7319c018c85elly  opts->sources = NULL;
1430e35d0568fb679664719bbb83ab6b7319c018c85elly  opts->cur_source = NULL;
144254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly  opts->proxy = NULL;
145c97feea2ab118d0aa4edaa7cad3c26b174cb693belly  opts->leap = 0;
146677a136165e23dccf2912fda529809d1a59bd428elly}
1473abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones
148677a136165e23dccf2912fda529809d1a59bd428ellyvoid
149c45952f88c568046a02bc0aea793008d8bb37755Will Drewryparse_argv (struct opts *opts, int argc, char *argv[])
150677a136165e23dccf2912fda529809d1a59bd428elly{
1513abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  int opt;
152aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  while ((opt = getopt (argc, argv, kTlsdatedOpts)) != -1)
1533abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    {
1543abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones      switch (opt)
155c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
156c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'w':
157c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_sync_hwclock = 0;
158c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
159c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'r':
160c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_netlink = 0;
161c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
1627daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry        case 'U':
1637daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry          opts->should_dbus = 0;
1647daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry          break;
165c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'p':
166c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->dry_run = 1;
167c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
168c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 't':
169c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->max_tries = atoi (optarg);
170c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
171c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'd':
172c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->wait_between_tries = atoi (optarg);
173c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
174c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'T':
175c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->subprocess_tries = atoi (optarg);
176c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
177c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'D':
178c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->subprocess_wait_between_tries = atoi (optarg);
179c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
180c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'c':
181c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->base_path = optarg;
182c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
183c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'a':
184c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->steady_state_interval = atoi (optarg);
185c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
186c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'l':
187c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_load_disk = 0;
188c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
189c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 's':
190c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_save_disk = 0;
191c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
192c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'v':
193c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          verbose = 1;
194c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
19547313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry        case 'b':
19647313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry          verbose_debug = 1;
19747313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry          break;
198c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'm':
199c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->min_steady_state_interval = atoi (optarg);
200c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
201c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'j':
202c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->jitter = atoi (optarg);
203c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
204c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'f':
205c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->conf_file = optarg;
206c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
207c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'x':
208c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->proxy = optarg;
209c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
210c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'u':
211c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->user = optarg;
212c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
213c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'g':
214c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->group = optarg;
215c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          break;
216aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold        case 'G':
217aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold          opts->supp_groups = optarg;
218aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold          break;
219c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        case 'h':
220c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        default:
221c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          usage (argv[0]);
222c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          exit (1);
223c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
2243abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    }
2253abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  if (optind < argc)
2260e35d0568fb679664719bbb83ab6b7319c018c85elly    opts->base_argv = argv + optind;
2273abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  /* Validate arguments */
228677a136165e23dccf2912fda529809d1a59bd428elly}
229677a136165e23dccf2912fda529809d1a59bd428elly
2300e35d0568fb679664719bbb83ab6b7319c018c85ellystatic
231c45952f88c568046a02bc0aea793008d8bb37755Will Drewryvoid add_source_to_conf (struct opts *opts, char *host, char *port, char *proxy)
2320e35d0568fb679664719bbb83ab6b7319c018c85elly{
2330e35d0568fb679664719bbb83ab6b7319c018c85elly  struct source *s;
2342d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry  struct source *source = (struct source *) calloc (1, sizeof *source);
2350e35d0568fb679664719bbb83ab6b7319c018c85elly  if (!source)
2360e35d0568fb679664719bbb83ab6b7319c018c85elly    fatal ("out of memory for source");
2370e35d0568fb679664719bbb83ab6b7319c018c85elly  source->host = strdup (host);
2380e35d0568fb679664719bbb83ab6b7319c018c85elly  if (!source->host)
2390e35d0568fb679664719bbb83ab6b7319c018c85elly    fatal ("out of memory for host");
2400e35d0568fb679664719bbb83ab6b7319c018c85elly  source->port = strdup (port);
2410e35d0568fb679664719bbb83ab6b7319c018c85elly  if (!source->port)
2420e35d0568fb679664719bbb83ab6b7319c018c85elly    fatal ("out of memory for port");
243c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (proxy)
244c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
245c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      source->proxy = strdup (proxy);
246c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (!source->proxy)
247c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        fatal ("out of memory for proxy");
248c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
249c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!opts->sources)
250c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
251c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      opts->sources = source;
252c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      source->id = 0;
253c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
254c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  else
255c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
256c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      for (s = opts->sources; s->next; s = s->next)
257c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        ;
258c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      source->id = s->id + 1;
259c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      s->next = source;
260c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
2610e35d0568fb679664719bbb83ab6b7319c018c85elly}
2620e35d0568fb679664719bbb83ab6b7319c018c85elly
2630e35d0568fb679664719bbb83ab6b7319c018c85ellystatic struct conf_entry *
264c45952f88c568046a02bc0aea793008d8bb37755Will Drewryparse_source (struct opts *opts, struct conf_entry *conf)
2650e35d0568fb679664719bbb83ab6b7319c018c85elly{
2660e35d0568fb679664719bbb83ab6b7319c018c85elly  char *host = NULL;
2670e35d0568fb679664719bbb83ab6b7319c018c85elly  char *port = NULL;
2680e35d0568fb679664719bbb83ab6b7319c018c85elly  char *proxy = NULL;
2690e35d0568fb679664719bbb83ab6b7319c018c85elly  /* a source entry:
2700e35d0568fb679664719bbb83ab6b7319c018c85elly   * source
2710e35d0568fb679664719bbb83ab6b7319c018c85elly   *   host <host>
2720e35d0568fb679664719bbb83ab6b7319c018c85elly   *   port <port>
273254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly   *   [proxy <proxy>]
2740e35d0568fb679664719bbb83ab6b7319c018c85elly   * end
2750e35d0568fb679664719bbb83ab6b7319c018c85elly   */
276c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  assert (!strcmp (conf->key, "source"));
2770e35d0568fb679664719bbb83ab6b7319c018c85elly  conf = conf->next;
278c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  while (conf && strcmp (conf->key, "end"))
279c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
280c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (!strcmp (conf->key, "host"))
281c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        host = conf->value;
282c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (conf->key, "port"))
283c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        port = conf->value;
284c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (conf->key, "proxy"))
285c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        proxy = conf->value;
286c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else
287c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        fatal ("malformed config: '%s' in source stanza", conf->key);
288c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      conf = conf->next;
289c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
2900e35d0568fb679664719bbb83ab6b7319c018c85elly  if (!conf)
2910e35d0568fb679664719bbb83ab6b7319c018c85elly    fatal ("unclosed source stanza");
292254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly  if (!host || !port)
293254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly    fatal ("incomplete source stanza (needs host, port)");
294c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  add_source_to_conf (opts, host, port, proxy);
2950e35d0568fb679664719bbb83ab6b7319c018c85elly  return conf;
2960e35d0568fb679664719bbb83ab6b7319c018c85elly}
2970e35d0568fb679664719bbb83ab6b7319c018c85elly
298677a136165e23dccf2912fda529809d1a59bd428ellyvoid
299c45952f88c568046a02bc0aea793008d8bb37755Will Drewryload_conf (struct opts *opts)
300677a136165e23dccf2912fda529809d1a59bd428elly{
301677a136165e23dccf2912fda529809d1a59bd428elly  FILE *f;
302677a136165e23dccf2912fda529809d1a59bd428elly  struct conf_entry *conf, *e;
303677a136165e23dccf2912fda529809d1a59bd428elly  char *conf_file = opts->conf_file;
304677a136165e23dccf2912fda529809d1a59bd428elly  if (!opts->conf_file)
3055b0ee57271eab109f103b42a326fc5b126e3bbdaJacob Appelbaum    conf_file = (char *) DEFAULT_CONF_FILE;
306677a136165e23dccf2912fda529809d1a59bd428elly  f = fopen (conf_file, "r");
307c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!f)
308c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
309c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (opts->conf_file)
310c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
311c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          pfatal ("can't open conf file '%s'", opts->conf_file);
312c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
313c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else
314c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
315c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          pinfo ("can't open conf file '%s'", conf_file);
316c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          return;
317c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
318677a136165e23dccf2912fda529809d1a59bd428elly    }
319677a136165e23dccf2912fda529809d1a59bd428elly  conf = conf_parse (f);
320677a136165e23dccf2912fda529809d1a59bd428elly  if (!conf)
321677a136165e23dccf2912fda529809d1a59bd428elly    pfatal ("can't parse config file");
322677a136165e23dccf2912fda529809d1a59bd428elly
323c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  for (e = conf; e; e = e->next)
324c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
325c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (!strcmp (e->key, "max-tries") && e->value)
326c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
327c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->max_tries = atoi (e->value);
328c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
329c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "min-steady-state-interval") && e->value)
330c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
331c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->min_steady_state_interval = atoi (e->value);
332c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
333c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "wait-between-tries") && e->value)
334c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
335c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->wait_between_tries = atoi (e->value);
336c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
337c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "subprocess-tries") && e->value)
338c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
339c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->subprocess_tries = atoi (e->value);
340c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
341c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "subprocess-wait-between-tries") && e->value)
342c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
343c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->subprocess_wait_between_tries = atoi (e->value);
344c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
345c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "steady-state-interval") && e->value)
346c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
347c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->steady_state_interval = atoi (e->value);
348c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
349c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "base-path") && e->value)
350c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
351c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->base_path = strdup (e->value);
352c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          if (!opts->base_path)
353c45952f88c568046a02bc0aea793008d8bb37755Will Drewry            fatal ("out of memory for base path");
354c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
355c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "should-sync-hwclock"))
356c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
357c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_sync_hwclock = e->value ? !strcmp (e->value, "yes") : 1;
358c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
359c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "should-load-disk"))
360c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
361c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_load_disk = e->value ? !strcmp (e->value, "yes") : 1;
362c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
363c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "should-save-disk"))
364c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
365c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_save_disk = e->value ? !strcmp (e->value, "yes") : 1;
366c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
367c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "should-netlink"))
368c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
369c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->should_netlink = e->value ? !strcmp (e->value, "yes") : 1;
370c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
371c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "dry-run"))
372c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
373c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->dry_run = e->value ? !strcmp (e->value, "yes") : 1;
374c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
375c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "jitter") && e->value)
376c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
377c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          opts->jitter = atoi (e->value);
378c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
379c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "verbose"))
380c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
381c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          verbose = e->value ? !strcmp (e->value, "yes") : 1;
382c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
383c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else if (!strcmp (e->key, "source"))
384c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
385c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          e = parse_source (opts, e);
386c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
3872d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry     else if (!strcmp (e->key, "leap"))
3882d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry        {
3892d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry          opts->leap = e->value ? !strcmp (e->value, "yes") : 1;
3902d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry        }
3912d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry   }
392677a136165e23dccf2912fda529809d1a59bd428elly}
393677a136165e23dccf2912fda529809d1a59bd428elly
394677a136165e23dccf2912fda529809d1a59bd428ellyvoid
395c45952f88c568046a02bc0aea793008d8bb37755Will Drewrycheck_conf (struct state *state)
396677a136165e23dccf2912fda529809d1a59bd428elly{
397c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct opts *opts = &state->opts;
398677a136165e23dccf2912fda529809d1a59bd428elly  if (!opts->max_tries)
3993abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    fatal ("-t argument must be nonzero");
400677a136165e23dccf2912fda529809d1a59bd428elly  if (!opts->wait_between_tries)
4013abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    fatal ("-d argument must be nonzero");
402677a136165e23dccf2912fda529809d1a59bd428elly  if (!opts->steady_state_interval)
4033abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    fatal ("-a argument must be nonzero");
404f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold  int ret = snprintf (state->timestamp_path, sizeof (state->timestamp_path),
405f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold		      "%s/timestamp", opts->base_path);
406f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold  if (ret < 0 || ((size_t) ret) >= sizeof (state->timestamp_path))
407677a136165e23dccf2912fda529809d1a59bd428elly    fatal ("supplied base path is too long: '%s'", opts->base_path);
408677a136165e23dccf2912fda529809d1a59bd428elly  if (opts->jitter >= opts->steady_state_interval)
409ccd12459a1abbc9825c298a5ac96a4cb84998985elly    fatal ("jitter must be less than steady state interval (%d >= %d)",
410677a136165e23dccf2912fda529809d1a59bd428elly           opts->jitter, opts->steady_state_interval);
411677a136165e23dccf2912fda529809d1a59bd428elly}
412677a136165e23dccf2912fda529809d1a59bd428elly
413c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint
414c45952f88c568046a02bc0aea793008d8bb37755Will Drewrycleanup_main (struct state *state)
415aa04c0126a590fc9646d491151bcbfeed34ba693elly{
416aa04c0126a590fc9646d491151bcbfeed34ba693elly  int i;
417c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  for (i = 0; i < E_MAX; ++i)
418c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
419c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      struct event *e = state->events[i];
420c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (e)
421c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
422c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          int fd = event_get_fd (e);
423c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL))
424c45952f88c568046a02bc0aea793008d8bb37755Will Drewry            close (fd);
425c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          event_free (e);
426c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
427c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
428c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* The other half was closed above. */
4299c331bf201909fb5a85725202eee872d4323e12dWill Drewry  platform->file_close (state->tlsdate_monitor_fd);
430c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state->tlsdate_pid)
431c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
4329c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->process_signal (state->tlsdate_pid, SIGKILL);
4339c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */);
434c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
435c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Best effort to tear it down if it is still alive. */
436c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  close(state->setter_notify_fd);
437c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  close(state->setter_save_fd);
438c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state->setter_pid)
439c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
4409c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->process_signal (state->setter_pid, SIGKILL);
4419c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->process_wait (state->setter_pid, NULL, 0 /* !forever */);
442c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
443c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* TODO(wad) Add dbus_cleanup() */
444c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state->base)
445c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    event_base_free (state->base);
446c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  memset(state, 0, sizeof(*state));
4474babadbb147ec9536f4ad29e74b00d008540c29dJacob Appelbaum  info ("tlsdated clean up finished; exiting!");
4488a3674582f83eec92ece411e464c56308c480ed3Jacob Appelbaum  terminate_syslog ();
449c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return 0;
450aa04c0126a590fc9646d491151bcbfeed34ba693elly}
451aa04c0126a590fc9646d491151bcbfeed34ba693elly
452c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#ifdef TLSDATED_MAIN
4534a0ae0177f07c62d336268082539dd64149aa288Gilad Arnoldstatic const char **
4544a0ae0177f07c62d336268082539dd64149aa288Gilad Arnoldparse_supp_groups (char *arg)
4554a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold{
4564a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  size_t i;
4574a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  char *scan;
4584a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  const char **supp_groups;
4594a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold
4604a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  for (i = 1, scan = arg; (scan = strchr (scan, ',')); i++, scan++) ;
4614a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  supp_groups = (const char **) calloc (i + 1, sizeof (const char *));
4624a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  if (!supp_groups)
4634a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold    die ("Failed to allocate memory for supplementary group names\n");
4644a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  for (i = 0; (supp_groups[i] = strsep (&arg, ",")); i++) ;
4654a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold  return supp_groups;
4664a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold}
4674a0ae0177f07c62d336268082539dd64149aa288Gilad Arnold
468677a136165e23dccf2912fda529809d1a59bd428ellyint API
469677a136165e23dccf2912fda529809d1a59bd428ellymain (int argc, char *argv[], char *envp[])
470677a136165e23dccf2912fda529809d1a59bd428elly{
471aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  const char **supp_groups = NULL;
472aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold
4738a3674582f83eec92ece411e464c56308c480ed3Jacob Appelbaum  initalize_syslog ();
474c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct state state;
475c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* TODO(wad) EVENT_BASE_FLAG_PRECISE_TIMER | EVENT_BASE_FLAG_PRECISE_TIMER */
476c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  struct event_base *base = event_base_new();
477c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!base)
478c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
479c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      fatal ("could not allocated new event base");
480c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
481c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Add three priority levels:
482c45952f88c568046a02bc0aea793008d8bb37755Will Drewry   * 0 - time saving.  Must be done before any other events are handled.
483c45952f88c568046a02bc0aea793008d8bb37755Will Drewry   * 1 - network synchronization events
484c45952f88c568046a02bc0aea793008d8bb37755Will Drewry   * 2 - any other events (wake, platform, etc)
485aa04c0126a590fc9646d491151bcbfeed34ba693elly   */
486c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  event_base_priority_init (base, MAX_EVENT_PRIORITIES);
487c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  memset (&state, 0, sizeof (state));
488c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  set_conf_defaults (&state.opts);
489c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  parse_argv (&state.opts, argc, argv);
490c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  check_conf (&state);
491c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  load_conf (&state.opts);
492c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  check_conf (&state);
493c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!state.opts.sources)
494c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY);
495c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.base = base;
496c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.envp = envp;
497c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.backoff = state.opts.wait_between_tries;
498c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* TODO(wad) move this into setup_time_setter */
4999c331bf201909fb5a85725202eee872d4323e12dWill Drewry  /* grab a handle to /dev/rtc for time-setter. */
500c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state.opts.should_sync_hwclock &&
5019c331bf201909fb5a85725202eee872d4323e12dWill Drewry      platform->rtc_open(&state.hwclock))
5023abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    {
503eac701bd7f37fa542ff9ad906c869195cda84d6cJacob Appelbaum      pinfo ("can't open hwclock fd");
504c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      state.opts.should_sync_hwclock = 0;
5053abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    }
506c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* install the SIGCHLD handler for the setter and tlsdate */
507c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_sigchld_event (&state, 1))
508aa04c0126a590fc9646d491151bcbfeed34ba693elly    {
509c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to setup SIGCHLD event");
510c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
511aa04c0126a590fc9646d491151bcbfeed34ba693elly    }
512c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* fork off the privileged helper */
513b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum  verb ("spawning time setting helper . . .");
514c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_time_setter (&state))
515aa04c0126a590fc9646d491151bcbfeed34ba693elly    {
516c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("could not fork privileged coprocess");
517c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
518aa04c0126a590fc9646d491151bcbfeed34ba693elly    }
519c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* release the hwclock now that the time-setter is running. */
52047313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry  if (state.opts.should_sync_hwclock)
52147313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry    {
52247313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry      platform->rtc_close (&state.hwclock);
52347313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry    }
524c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* drop privileges before touching any untrusted data */
525aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  if (state.opts.supp_groups)
526aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold    supp_groups = parse_supp_groups (state.opts.supp_groups);
527aab9382297008c1d1b7cef361159a44885d52af0Gilad Arnold  drop_privs_to (state.opts.user, state.opts.group, supp_groups);
528727698b640dad91c1016d26e6cac74e5bc893598Gilad Arnold  free (supp_groups);
5293abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones  /* register a signal handler to save time at shutdown */
530c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state.opts.should_save_disk)
5313abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    {
532c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      struct event *event = event_new (base, SIGTERM, EV_SIGNAL|EV_PERSIST,
533c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                                       action_sigterm, &state);
534c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (!event)
535c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        fatal ("Failed to create SIGTERM event");
536c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      event_priority_set (event, PRI_SAVE);
537c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      event_add (event, NULL);
5383abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones    }
5397daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry  if (state.opts.should_dbus && init_dbus (&state))
540c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
541c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to initialize DBus");
542c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
543c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
544c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Register the tlsdate event before any listeners could show up. */
545c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.events[E_TLSDATE] = event_new (base, -1, EV_TIMEOUT,
546c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                                       action_run_tlsdate, &state);
547c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!state.events[E_TLSDATE])
548c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
549c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to create tlsdate event");
550c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
551c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
552c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  event_priority_set (state.events[E_TLSDATE], PRI_NET);
553c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* The timeout and fd will be filled in per-call. */
554c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_tlsdate_status (&state))
555c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
556c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to create tlsdate status event");
557c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
558c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
559c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* TODO(wad) Could use a timeout on this to catch setter death? */
560c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* EV_READ is for truncation/EPIPE notification */
561c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.events[E_SAVE] = event_new (base, state.setter_save_fd,
562c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                                    EV_READ|EV_WRITE, action_sync_and_save,
563c45952f88c568046a02bc0aea793008d8bb37755Will Drewry                                    &state);
564c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!state.events[E_SAVE])
565c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
566c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to create sync & save event");
567c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
568c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
569c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  event_priority_set (state.events[E_SAVE], PRI_SAVE);
570c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Start by grabbing the system time. */
571c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.last_sync_type = SYNC_TYPE_RTC;
572c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  state.last_time = time (NULL);
573c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* If possible, grab disk time and check the two. */
574c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (state.opts.should_load_disk)
575c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
576c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      time_t disk_time = state.last_time;
577c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      if (!load_disk_timestamp (state.timestamp_path, &disk_time))
578c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
579e9132c014d2a05e410f98cb777a4806dddde3e8eGilad Arnold          verb ("disk timestamp available: yes (%ld)", disk_time);
580c45952f88c568046a02bc0aea793008d8bb37755Will Drewry          if (!is_sane_time (state.last_time) ||
581c45952f88c568046a02bc0aea793008d8bb37755Will Drewry              state.last_time < disk_time)
582c45952f88c568046a02bc0aea793008d8bb37755Will Drewry            {
583c45952f88c568046a02bc0aea793008d8bb37755Will Drewry              state.last_sync_type = SYNC_TYPE_DISK;
584c45952f88c568046a02bc0aea793008d8bb37755Will Drewry              state.last_time = disk_time;
585c45952f88c568046a02bc0aea793008d8bb37755Will Drewry            }
586c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
587c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      else
588c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        {
589b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum          verb ("disk timestamp available: no");
590c45952f88c568046a02bc0aea793008d8bb37755Will Drewry        }
591c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
592c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (!is_sane_time (state.last_time))
593c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
594c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      state.last_sync_type = SYNC_TYPE_BUILD;
595c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      state.last_time = RECENT_COMPILE_DATE + 1;
596c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
597c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Save and announce the initial time source. */
598c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  trigger_event (&state, E_SAVE, -1);
599e11d02fe1d54baaf2bd1a5f98942455553f453f8Jacob Appelbaum  verb ("tlsdated parasitic time synchronization initialized");
600c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  info ("initial time sync type: %s", sync_type_str (state.last_sync_type));
601c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Initialize platform specific loop behavior */
602c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (platform_init_cros (&state))
603c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
604c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to initialize platform code");
605c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
606c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
607c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_event_route_up (&state))
608c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
609c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to setup route up monitoring");
610c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
611c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
612c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_event_timer_sync (&state))
613c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
614c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to setup a timer event");
615c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
616c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
617c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  if (setup_event_timer_continuity (&state))
618c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    {
619c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      error ("Failed to setup continuity timer");
620c45952f88c568046a02bc0aea793008d8bb37755Will Drewry      goto out;
621c45952f88c568046a02bc0aea793008d8bb37755Will Drewry    }
622c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  /* Add a forced sync event to the event list. */
623c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  action_kickoff_time_sync (-1, EV_TIMEOUT, &state);
624b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum  verb ("Entering dispatch . . .");
625c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  event_base_dispatch (base);
626c79e118e77fe6a9964964c5782330b9b4ebf5ab5Jacob Appelbaum  verb ("tlsdated event dispatch terminating gracefully");
627c45952f88c568046a02bc0aea793008d8bb37755Will Drewryout:
628c45952f88c568046a02bc0aea793008d8bb37755Will Drewry  return cleanup_main (&state);
6296fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones}
6306fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#endif /* !TLSDATED_MAIN */
631