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