tlsdated.c revision f162a324dd2c6bd9aa08741fc623d134eecbc2cf
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 452efca57f2b02922aa50648d11b1a90559d863612Jacob Appelbaumconst char *kCacheDir = DEFAULT_DAEMON_CACHEDIR; 466fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones 473abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesint 483abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesis_sane_time (time_t ts) 496fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{ 503abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones return ts > RECENT_COMPILE_DATE && ts < TLSDATED_MAX_DATE; 516fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones} 526fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones 536fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones/* 546fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * Load a time value out of the file named by path. Returns 0 if successful, 556fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * -1 if not. The file contains the time in seconds since epoch in host byte 566fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones * order. 576fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones */ 583abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesint 593abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesload_disk_timestamp (const char *path, time_t * t) 606fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{ 619c331bf201909fb5a85725202eee872d4323e12dWill Drewry int fd = platform->file_open (path, 0 /* RDONLY */, 1 /* CLOEXEC */); 629c331bf201909fb5a85725202eee872d4323e12dWill Drewry time_t tmpt = 0; 633abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones if (fd < 0) 643abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones { 653abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones perror ("Can't open %s for reading", path); 663abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones return -1; 673abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones } 689c331bf201909fb5a85725202eee872d4323e12dWill Drewry if (platform->file_read(fd, &tmpt, sizeof(tmpt))) 69385386d927176a47bc71b7efaf51fb7806f72d80Paul Bakker { 703abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones perror ("Can't read seconds from %s", path); 719c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->file_close (fd); 723abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones return -1; 73385386d927176a47bc71b7efaf51fb7806f72d80Paul Bakker } 749c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->file_close (fd); 753abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones if (!is_sane_time (tmpt)) 763abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones { 77c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Disk timestamp is not sane: %ld", tmpt); 783abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones return -1; 793abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones } 803abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones *t = tmpt; 813abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones return 0; 826fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones} 836fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones 84aa04c0126a590fc9646d491151bcbfeed34ba693elly 85aa04c0126a590fc9646d491151bcbfeed34ba693ellyvoid 863abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jonesusage (const char *progn) 876fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{ 883abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf ("Usage: %s [flags...] [--] [tlsdate command...]\n", progn); 893abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -w don't set hwclock\n"); 903abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -p dry run (don't really set time)\n"); 913abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -r use stdin instead of netlink for routes\n"); 9247313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry printf (" -t <n> try n times to synchronize the time\n"); 933abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -d <n> delay n seconds between tries\n"); 943abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -T <n> give subprocess n chances to exit\n"); 953abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -D <n> delay n seconds between wait attempts\n"); 963abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -c <path> set the cache directory\n"); 973abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -a <n> run at most every n seconds in steady state\n"); 98f44f6232679fabdb5d3486b1691e6253c3a6a8abElly Fong-Jones printf (" -m <n> run at most once every n seconds in steady state\n"); 99ccd12459a1abbc9825c298a5ac96a4cb84998985elly printf (" -j <n> add up to n seconds jitter to steady state checks\n"); 1003abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -l don't load disk timestamps\n"); 1013abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -s don't save disk timestamps\n"); 1027daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry printf (" -U don't use DBus if supported\n"); 103c45952f88c568046a02bc0aea793008d8bb37755Will Drewry printf (" -u <user> user to change to\n"); 104c45952f88c568046a02bc0aea793008d8bb37755Will Drewry printf (" -g <grp> group to change to\n"); 1053abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -v be verbose\n"); 10647313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry printf (" -b use verbose debugging\n"); 107254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly printf (" -x <h> set proxy for subprocs to h\n"); 1083abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones printf (" -h this\n"); 1096fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones} 1106fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones 111677a136165e23dccf2912fda529809d1a59bd428ellyvoid 112c45952f88c568046a02bc0aea793008d8bb37755Will Drewryset_conf_defaults (struct opts *opts) 1136fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones{ 114c45952f88c568046a02bc0aea793008d8bb37755Will Drewry static char *kDefaultArgv[] = 115c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 1165b0ee57271eab109f103b42a326fc5b126e3bbdaJacob Appelbaum (char *) DEFAULT_TLSDATE, (char *) "-H", (char *) DEFAULT_HOST, NULL 1173abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones }; 118c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->user = UNPRIV_USER; 119c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->group = UNPRIV_GROUP; 120677a136165e23dccf2912fda529809d1a59bd428elly opts->max_tries = MAX_TRIES; 121677a136165e23dccf2912fda529809d1a59bd428elly opts->min_steady_state_interval = STEADY_STATE_INTERVAL; 122677a136165e23dccf2912fda529809d1a59bd428elly opts->wait_between_tries = WAIT_BETWEEN_TRIES; 123677a136165e23dccf2912fda529809d1a59bd428elly opts->subprocess_tries = SUBPROCESS_TRIES; 124677a136165e23dccf2912fda529809d1a59bd428elly opts->subprocess_wait_between_tries = SUBPROCESS_WAIT_BETWEEN_TRIES; 125677a136165e23dccf2912fda529809d1a59bd428elly opts->steady_state_interval = STEADY_STATE_INTERVAL; 126c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->continuity_interval = CONTINUITY_INTERVAL; 127677a136165e23dccf2912fda529809d1a59bd428elly opts->base_path = kCacheDir; 1280e35d0568fb679664719bbb83ab6b7319c018c85elly opts->base_argv = kDefaultArgv; 1290e35d0568fb679664719bbb83ab6b7319c018c85elly opts->argv = NULL; 1307daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry opts->should_dbus = 1; 131677a136165e23dccf2912fda529809d1a59bd428elly opts->should_sync_hwclock = DEFAULT_SYNC_HWCLOCK; 132677a136165e23dccf2912fda529809d1a59bd428elly opts->should_load_disk = DEFAULT_LOAD_FROM_DISK; 133677a136165e23dccf2912fda529809d1a59bd428elly opts->should_save_disk = DEFAULT_SAVE_TO_DISK; 134677a136165e23dccf2912fda529809d1a59bd428elly opts->should_netlink = DEFAULT_USE_NETLINK; 135677a136165e23dccf2912fda529809d1a59bd428elly opts->dry_run = DEFAULT_DRY_RUN; 136677a136165e23dccf2912fda529809d1a59bd428elly opts->jitter = 0; 137677a136165e23dccf2912fda529809d1a59bd428elly opts->conf_file = NULL; 1380e35d0568fb679664719bbb83ab6b7319c018c85elly opts->sources = NULL; 1390e35d0568fb679664719bbb83ab6b7319c018c85elly opts->cur_source = NULL; 140254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly opts->proxy = NULL; 141c97feea2ab118d0aa4edaa7cad3c26b174cb693belly opts->leap = 0; 142677a136165e23dccf2912fda529809d1a59bd428elly} 1433abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones 144677a136165e23dccf2912fda529809d1a59bd428ellyvoid 145c45952f88c568046a02bc0aea793008d8bb37755Will Drewryparse_argv (struct opts *opts, int argc, char *argv[]) 146677a136165e23dccf2912fda529809d1a59bd428elly{ 1473abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones int opt; 14847313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry while ((opt = getopt (argc, argv, "hwrpt:d:T:D:c:a:lsvbm:j:f:x:Uu:g:")) != -1) 1493abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones { 1503abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones switch (opt) 151c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 152c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'w': 153c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_sync_hwclock = 0; 154c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 155c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'r': 156c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_netlink = 0; 157c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 1587daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry case 'U': 1597daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry opts->should_dbus = 0; 1607daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry break; 161c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'p': 162c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->dry_run = 1; 163c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 164c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 't': 165c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->max_tries = atoi (optarg); 166c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 167c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'd': 168c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->wait_between_tries = atoi (optarg); 169c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 170c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'T': 171c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->subprocess_tries = atoi (optarg); 172c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 173c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'D': 174c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->subprocess_wait_between_tries = atoi (optarg); 175c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 176c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'c': 177c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->base_path = optarg; 178c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 179c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'a': 180c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->steady_state_interval = atoi (optarg); 181c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 182c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'l': 183c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_load_disk = 0; 184c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 185c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 's': 186c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_save_disk = 0; 187c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 188c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'v': 189c45952f88c568046a02bc0aea793008d8bb37755Will Drewry verbose = 1; 190c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 19147313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry case 'b': 19247313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry verbose_debug = 1; 19347313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry break; 194c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'm': 195c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->min_steady_state_interval = atoi (optarg); 196c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 197c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'j': 198c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->jitter = atoi (optarg); 199c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 200c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'f': 201c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->conf_file = optarg; 202c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 203c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'x': 204c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->proxy = optarg; 205c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 206c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'u': 207c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->user = optarg; 208c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 209c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'g': 210c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->group = optarg; 211c45952f88c568046a02bc0aea793008d8bb37755Will Drewry break; 212c45952f88c568046a02bc0aea793008d8bb37755Will Drewry case 'h': 213c45952f88c568046a02bc0aea793008d8bb37755Will Drewry default: 214c45952f88c568046a02bc0aea793008d8bb37755Will Drewry usage (argv[0]); 215c45952f88c568046a02bc0aea793008d8bb37755Will Drewry exit (1); 216c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 2173abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones } 2183abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones if (optind < argc) 2190e35d0568fb679664719bbb83ab6b7319c018c85elly opts->base_argv = argv + optind; 2203abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones /* Validate arguments */ 221677a136165e23dccf2912fda529809d1a59bd428elly} 222677a136165e23dccf2912fda529809d1a59bd428elly 2230e35d0568fb679664719bbb83ab6b7319c018c85ellystatic 224c45952f88c568046a02bc0aea793008d8bb37755Will Drewryvoid add_source_to_conf (struct opts *opts, char *host, char *port, char *proxy) 2250e35d0568fb679664719bbb83ab6b7319c018c85elly{ 2260e35d0568fb679664719bbb83ab6b7319c018c85elly struct source *s; 2272d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry struct source *source = (struct source *) calloc (1, sizeof *source); 2280e35d0568fb679664719bbb83ab6b7319c018c85elly if (!source) 2290e35d0568fb679664719bbb83ab6b7319c018c85elly fatal ("out of memory for source"); 2300e35d0568fb679664719bbb83ab6b7319c018c85elly source->host = strdup (host); 2310e35d0568fb679664719bbb83ab6b7319c018c85elly if (!source->host) 2320e35d0568fb679664719bbb83ab6b7319c018c85elly fatal ("out of memory for host"); 2330e35d0568fb679664719bbb83ab6b7319c018c85elly source->port = strdup (port); 2340e35d0568fb679664719bbb83ab6b7319c018c85elly if (!source->port) 2350e35d0568fb679664719bbb83ab6b7319c018c85elly fatal ("out of memory for port"); 236c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (proxy) 237c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 238c45952f88c568046a02bc0aea793008d8bb37755Will Drewry source->proxy = strdup (proxy); 239c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!source->proxy) 240c45952f88c568046a02bc0aea793008d8bb37755Will Drewry fatal ("out of memory for proxy"); 241c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 242c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!opts->sources) 243c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 244c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->sources = source; 245c45952f88c568046a02bc0aea793008d8bb37755Will Drewry source->id = 0; 246c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 247c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else 248c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 249c45952f88c568046a02bc0aea793008d8bb37755Will Drewry for (s = opts->sources; s->next; s = s->next) 250c45952f88c568046a02bc0aea793008d8bb37755Will Drewry ; 251c45952f88c568046a02bc0aea793008d8bb37755Will Drewry source->id = s->id + 1; 252c45952f88c568046a02bc0aea793008d8bb37755Will Drewry s->next = source; 253c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 2540e35d0568fb679664719bbb83ab6b7319c018c85elly} 2550e35d0568fb679664719bbb83ab6b7319c018c85elly 2560e35d0568fb679664719bbb83ab6b7319c018c85ellystatic struct conf_entry * 257c45952f88c568046a02bc0aea793008d8bb37755Will Drewryparse_source (struct opts *opts, struct conf_entry *conf) 2580e35d0568fb679664719bbb83ab6b7319c018c85elly{ 2590e35d0568fb679664719bbb83ab6b7319c018c85elly char *host = NULL; 2600e35d0568fb679664719bbb83ab6b7319c018c85elly char *port = NULL; 2610e35d0568fb679664719bbb83ab6b7319c018c85elly char *proxy = NULL; 2620e35d0568fb679664719bbb83ab6b7319c018c85elly /* a source entry: 2630e35d0568fb679664719bbb83ab6b7319c018c85elly * source 2640e35d0568fb679664719bbb83ab6b7319c018c85elly * host <host> 2650e35d0568fb679664719bbb83ab6b7319c018c85elly * port <port> 266254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly * [proxy <proxy>] 2670e35d0568fb679664719bbb83ab6b7319c018c85elly * end 2680e35d0568fb679664719bbb83ab6b7319c018c85elly */ 269c45952f88c568046a02bc0aea793008d8bb37755Will Drewry assert (!strcmp (conf->key, "source")); 2700e35d0568fb679664719bbb83ab6b7319c018c85elly conf = conf->next; 271c45952f88c568046a02bc0aea793008d8bb37755Will Drewry while (conf && strcmp (conf->key, "end")) 272c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 273c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!strcmp (conf->key, "host")) 274c45952f88c568046a02bc0aea793008d8bb37755Will Drewry host = conf->value; 275c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (conf->key, "port")) 276c45952f88c568046a02bc0aea793008d8bb37755Will Drewry port = conf->value; 277c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (conf->key, "proxy")) 278c45952f88c568046a02bc0aea793008d8bb37755Will Drewry proxy = conf->value; 279c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else 280c45952f88c568046a02bc0aea793008d8bb37755Will Drewry fatal ("malformed config: '%s' in source stanza", conf->key); 281c45952f88c568046a02bc0aea793008d8bb37755Will Drewry conf = conf->next; 282c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 2830e35d0568fb679664719bbb83ab6b7319c018c85elly if (!conf) 2840e35d0568fb679664719bbb83ab6b7319c018c85elly fatal ("unclosed source stanza"); 285254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly if (!host || !port) 286254dc20bbaa68f955b1de8c7da6a02d52c786fd0elly fatal ("incomplete source stanza (needs host, port)"); 287c45952f88c568046a02bc0aea793008d8bb37755Will Drewry add_source_to_conf (opts, host, port, proxy); 2880e35d0568fb679664719bbb83ab6b7319c018c85elly return conf; 2890e35d0568fb679664719bbb83ab6b7319c018c85elly} 2900e35d0568fb679664719bbb83ab6b7319c018c85elly 291677a136165e23dccf2912fda529809d1a59bd428ellyvoid 292c45952f88c568046a02bc0aea793008d8bb37755Will Drewryload_conf (struct opts *opts) 293677a136165e23dccf2912fda529809d1a59bd428elly{ 294677a136165e23dccf2912fda529809d1a59bd428elly FILE *f; 295677a136165e23dccf2912fda529809d1a59bd428elly struct conf_entry *conf, *e; 296677a136165e23dccf2912fda529809d1a59bd428elly char *conf_file = opts->conf_file; 297677a136165e23dccf2912fda529809d1a59bd428elly if (!opts->conf_file) 2985b0ee57271eab109f103b42a326fc5b126e3bbdaJacob Appelbaum conf_file = (char *) DEFAULT_CONF_FILE; 299677a136165e23dccf2912fda529809d1a59bd428elly f = fopen (conf_file, "r"); 300c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!f) 301c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 302c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (opts->conf_file) 303c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 304c45952f88c568046a02bc0aea793008d8bb37755Will Drewry pfatal ("can't open conf file '%s'", opts->conf_file); 305c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 306c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else 307c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 308c45952f88c568046a02bc0aea793008d8bb37755Will Drewry pinfo ("can't open conf file '%s'", conf_file); 309c45952f88c568046a02bc0aea793008d8bb37755Will Drewry return; 310c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 311677a136165e23dccf2912fda529809d1a59bd428elly } 312677a136165e23dccf2912fda529809d1a59bd428elly conf = conf_parse (f); 313677a136165e23dccf2912fda529809d1a59bd428elly if (!conf) 314677a136165e23dccf2912fda529809d1a59bd428elly pfatal ("can't parse config file"); 315677a136165e23dccf2912fda529809d1a59bd428elly 316c45952f88c568046a02bc0aea793008d8bb37755Will Drewry for (e = conf; e; e = e->next) 317c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 318c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!strcmp (e->key, "max-tries") && e->value) 319c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 320c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->max_tries = atoi (e->value); 321c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 322c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "min-steady-state-interval") && e->value) 323c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 324c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->min_steady_state_interval = atoi (e->value); 325c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 326c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "wait-between-tries") && e->value) 327c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 328c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->wait_between_tries = atoi (e->value); 329c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 330c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "subprocess-tries") && e->value) 331c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 332c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->subprocess_tries = atoi (e->value); 333c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 334c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "subprocess-wait-between-tries") && e->value) 335c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 336c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->subprocess_wait_between_tries = atoi (e->value); 337c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 338c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "steady-state-interval") && e->value) 339c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 340c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->steady_state_interval = atoi (e->value); 341c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 342c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "base-path") && e->value) 343c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 344c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->base_path = strdup (e->value); 345c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!opts->base_path) 346c45952f88c568046a02bc0aea793008d8bb37755Will Drewry fatal ("out of memory for base path"); 347c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 348c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "should-sync-hwclock")) 349c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 350c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_sync_hwclock = e->value ? !strcmp (e->value, "yes") : 1; 351c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 352c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "should-load-disk")) 353c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 354c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_load_disk = e->value ? !strcmp (e->value, "yes") : 1; 355c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 356c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "should-save-disk")) 357c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 358c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_save_disk = e->value ? !strcmp (e->value, "yes") : 1; 359c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 360c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "should-netlink")) 361c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 362c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->should_netlink = e->value ? !strcmp (e->value, "yes") : 1; 363c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 364c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "dry-run")) 365c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 366c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->dry_run = e->value ? !strcmp (e->value, "yes") : 1; 367c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 368c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "jitter") && e->value) 369c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 370c45952f88c568046a02bc0aea793008d8bb37755Will Drewry opts->jitter = atoi (e->value); 371c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 372c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "verbose")) 373c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 374c45952f88c568046a02bc0aea793008d8bb37755Will Drewry verbose = e->value ? !strcmp (e->value, "yes") : 1; 375c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 376c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else if (!strcmp (e->key, "source")) 377c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 378c45952f88c568046a02bc0aea793008d8bb37755Will Drewry e = parse_source (opts, e); 379c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 3802d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry else if (!strcmp (e->key, "leap")) 3812d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry { 3822d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry opts->leap = e->value ? !strcmp (e->value, "yes") : 1; 3832d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry } 3842d9fd234e2887fdb29c6c09f66ade0a8b32c3ba7Will Drewry } 385677a136165e23dccf2912fda529809d1a59bd428elly} 386677a136165e23dccf2912fda529809d1a59bd428elly 387677a136165e23dccf2912fda529809d1a59bd428ellyvoid 388c45952f88c568046a02bc0aea793008d8bb37755Will Drewrycheck_conf (struct state *state) 389677a136165e23dccf2912fda529809d1a59bd428elly{ 390c45952f88c568046a02bc0aea793008d8bb37755Will Drewry struct opts *opts = &state->opts; 391677a136165e23dccf2912fda529809d1a59bd428elly if (!opts->max_tries) 3923abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones fatal ("-t argument must be nonzero"); 393677a136165e23dccf2912fda529809d1a59bd428elly if (!opts->wait_between_tries) 3943abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones fatal ("-d argument must be nonzero"); 395677a136165e23dccf2912fda529809d1a59bd428elly if (!opts->steady_state_interval) 3963abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones fatal ("-a argument must be nonzero"); 397f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold int ret = snprintf (state->timestamp_path, sizeof (state->timestamp_path), 398f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold "%s/timestamp", opts->base_path); 399f162a324dd2c6bd9aa08741fc623d134eecbc2cfGilad Arnold if (ret < 0 || ((size_t) ret) >= sizeof (state->timestamp_path)) 400677a136165e23dccf2912fda529809d1a59bd428elly fatal ("supplied base path is too long: '%s'", opts->base_path); 401677a136165e23dccf2912fda529809d1a59bd428elly if (opts->jitter >= opts->steady_state_interval) 402ccd12459a1abbc9825c298a5ac96a4cb84998985elly fatal ("jitter must be less than steady state interval (%d >= %d)", 403677a136165e23dccf2912fda529809d1a59bd428elly opts->jitter, opts->steady_state_interval); 404677a136165e23dccf2912fda529809d1a59bd428elly} 405677a136165e23dccf2912fda529809d1a59bd428elly 406c45952f88c568046a02bc0aea793008d8bb37755Will Drewryint 407c45952f88c568046a02bc0aea793008d8bb37755Will Drewrycleanup_main (struct state *state) 408aa04c0126a590fc9646d491151bcbfeed34ba693elly{ 409aa04c0126a590fc9646d491151bcbfeed34ba693elly int i; 410c45952f88c568046a02bc0aea793008d8bb37755Will Drewry for (i = 0; i < E_MAX; ++i) 411c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 412c45952f88c568046a02bc0aea793008d8bb37755Will Drewry struct event *e = state->events[i]; 413c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (e) 414c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 415c45952f88c568046a02bc0aea793008d8bb37755Will Drewry int fd = event_get_fd (e); 416c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (fd >= 0 && ! (event_get_events (e) & EV_SIGNAL)) 417c45952f88c568046a02bc0aea793008d8bb37755Will Drewry close (fd); 418c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_free (e); 419c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 420c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 421c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* The other half was closed above. */ 4229c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->file_close (state->tlsdate_monitor_fd); 423c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state->tlsdate_pid) 424c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 4259c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->process_signal (state->tlsdate_pid, SIGKILL); 4269c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->process_wait (state->tlsdate_pid, NULL, 0 /* !forever */); 427c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 428c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Best effort to tear it down if it is still alive. */ 429c45952f88c568046a02bc0aea793008d8bb37755Will Drewry close(state->setter_notify_fd); 430c45952f88c568046a02bc0aea793008d8bb37755Will Drewry close(state->setter_save_fd); 431c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state->setter_pid) 432c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 4339c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->process_signal (state->setter_pid, SIGKILL); 4349c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->process_wait (state->setter_pid, NULL, 0 /* !forever */); 435c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 436c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* TODO(wad) Add dbus_cleanup() */ 437c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state->base) 438c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_base_free (state->base); 439c45952f88c568046a02bc0aea793008d8bb37755Will Drewry memset(state, 0, sizeof(*state)); 4404babadbb147ec9536f4ad29e74b00d008540c29dJacob Appelbaum info ("tlsdated clean up finished; exiting!"); 4418a3674582f83eec92ece411e464c56308c480ed3Jacob Appelbaum terminate_syslog (); 442c45952f88c568046a02bc0aea793008d8bb37755Will Drewry return 0; 443aa04c0126a590fc9646d491151bcbfeed34ba693elly} 444aa04c0126a590fc9646d491151bcbfeed34ba693elly 445c45952f88c568046a02bc0aea793008d8bb37755Will Drewry#ifdef TLSDATED_MAIN 446677a136165e23dccf2912fda529809d1a59bd428ellyint API 447677a136165e23dccf2912fda529809d1a59bd428ellymain (int argc, char *argv[], char *envp[]) 448677a136165e23dccf2912fda529809d1a59bd428elly{ 4498a3674582f83eec92ece411e464c56308c480ed3Jacob Appelbaum initalize_syslog (); 450c45952f88c568046a02bc0aea793008d8bb37755Will Drewry struct state state; 451c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* TODO(wad) EVENT_BASE_FLAG_PRECISE_TIMER | EVENT_BASE_FLAG_PRECISE_TIMER */ 452c45952f88c568046a02bc0aea793008d8bb37755Will Drewry struct event_base *base = event_base_new(); 453c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!base) 454c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 455c45952f88c568046a02bc0aea793008d8bb37755Will Drewry fatal ("could not allocated new event base"); 456c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 457c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Add three priority levels: 458c45952f88c568046a02bc0aea793008d8bb37755Will Drewry * 0 - time saving. Must be done before any other events are handled. 459c45952f88c568046a02bc0aea793008d8bb37755Will Drewry * 1 - network synchronization events 460c45952f88c568046a02bc0aea793008d8bb37755Will Drewry * 2 - any other events (wake, platform, etc) 461aa04c0126a590fc9646d491151bcbfeed34ba693elly */ 462c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_base_priority_init (base, MAX_EVENT_PRIORITIES); 463c45952f88c568046a02bc0aea793008d8bb37755Will Drewry memset (&state, 0, sizeof (state)); 464c45952f88c568046a02bc0aea793008d8bb37755Will Drewry set_conf_defaults (&state.opts); 465c45952f88c568046a02bc0aea793008d8bb37755Will Drewry parse_argv (&state.opts, argc, argv); 466c45952f88c568046a02bc0aea793008d8bb37755Will Drewry check_conf (&state); 467c45952f88c568046a02bc0aea793008d8bb37755Will Drewry load_conf (&state.opts); 468c45952f88c568046a02bc0aea793008d8bb37755Will Drewry check_conf (&state); 469c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!state.opts.sources) 470c45952f88c568046a02bc0aea793008d8bb37755Will Drewry add_source_to_conf (&state.opts, DEFAULT_HOST, DEFAULT_PORT, DEFAULT_PROXY); 471c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.base = base; 472c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.envp = envp; 473c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.backoff = state.opts.wait_between_tries; 474c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* TODO(wad) move this into setup_time_setter */ 4759c331bf201909fb5a85725202eee872d4323e12dWill Drewry /* grab a handle to /dev/rtc for time-setter. */ 476c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state.opts.should_sync_hwclock && 4779c331bf201909fb5a85725202eee872d4323e12dWill Drewry platform->rtc_open(&state.hwclock)) 4783abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones { 479eac701bd7f37fa542ff9ad906c869195cda84d6cJacob Appelbaum pinfo ("can't open hwclock fd"); 480c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.opts.should_sync_hwclock = 0; 4813abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones } 482c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* install the SIGCHLD handler for the setter and tlsdate */ 483c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_sigchld_event (&state, 1)) 484aa04c0126a590fc9646d491151bcbfeed34ba693elly { 485c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to setup SIGCHLD event"); 486c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 487aa04c0126a590fc9646d491151bcbfeed34ba693elly } 488c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* fork off the privileged helper */ 489b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum verb ("spawning time setting helper . . ."); 490c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_time_setter (&state)) 491aa04c0126a590fc9646d491151bcbfeed34ba693elly { 492c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("could not fork privileged coprocess"); 493c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 494aa04c0126a590fc9646d491151bcbfeed34ba693elly } 495c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* release the hwclock now that the time-setter is running. */ 49647313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry if (state.opts.should_sync_hwclock) 49747313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry { 49847313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry platform->rtc_close (&state.hwclock); 49947313d1f1ae3749f69ad0344e8125f1d61f6faedWill Drewry } 500c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* drop privileges before touching any untrusted data */ 501c45952f88c568046a02bc0aea793008d8bb37755Will Drewry drop_privs_to (state.opts.user, state.opts.group); 5023abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones /* register a signal handler to save time at shutdown */ 503c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state.opts.should_save_disk) 5043abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones { 505c45952f88c568046a02bc0aea793008d8bb37755Will Drewry struct event *event = event_new (base, SIGTERM, EV_SIGNAL|EV_PERSIST, 506c45952f88c568046a02bc0aea793008d8bb37755Will Drewry action_sigterm, &state); 507c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!event) 508c45952f88c568046a02bc0aea793008d8bb37755Will Drewry fatal ("Failed to create SIGTERM event"); 509c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_priority_set (event, PRI_SAVE); 510c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_add (event, NULL); 5113abea72f9bd82469f4e7fda3384f76cc866da236Elly Fong-Jones } 5127daea59e81770f9ba5f1ba2b04d7f31b4828e5fcWill Drewry if (state.opts.should_dbus && init_dbus (&state)) 513c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 514c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to initialize DBus"); 515c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 516c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 517c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Register the tlsdate event before any listeners could show up. */ 518c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.events[E_TLSDATE] = event_new (base, -1, EV_TIMEOUT, 519c45952f88c568046a02bc0aea793008d8bb37755Will Drewry action_run_tlsdate, &state); 520c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!state.events[E_TLSDATE]) 521c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 522c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to create tlsdate event"); 523c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 524c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 525c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_priority_set (state.events[E_TLSDATE], PRI_NET); 526c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* The timeout and fd will be filled in per-call. */ 527c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_tlsdate_status (&state)) 528c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 529c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to create tlsdate status event"); 530c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 531c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 532c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* TODO(wad) Could use a timeout on this to catch setter death? */ 533c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* EV_READ is for truncation/EPIPE notification */ 534c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.events[E_SAVE] = event_new (base, state.setter_save_fd, 535c45952f88c568046a02bc0aea793008d8bb37755Will Drewry EV_READ|EV_WRITE, action_sync_and_save, 536c45952f88c568046a02bc0aea793008d8bb37755Will Drewry &state); 537c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!state.events[E_SAVE]) 538c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 539c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to create sync & save event"); 540c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 541c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 542c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_priority_set (state.events[E_SAVE], PRI_SAVE); 543c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Start by grabbing the system time. */ 544c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_sync_type = SYNC_TYPE_RTC; 545c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_time = time (NULL); 546c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* If possible, grab disk time and check the two. */ 547c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (state.opts.should_load_disk) 548c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 549c45952f88c568046a02bc0aea793008d8bb37755Will Drewry time_t disk_time = state.last_time; 550c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!load_disk_timestamp (state.timestamp_path, &disk_time)) 551c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 552b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum verb ("disk timestamp available: yes"); 553c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!is_sane_time (state.last_time) || 554c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_time < disk_time) 555c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 556c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_sync_type = SYNC_TYPE_DISK; 557c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_time = disk_time; 558c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 559c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 560c45952f88c568046a02bc0aea793008d8bb37755Will Drewry else 561c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 562b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum verb ("disk timestamp available: no"); 563c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 564c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 565c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (!is_sane_time (state.last_time)) 566c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 567c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_sync_type = SYNC_TYPE_BUILD; 568c45952f88c568046a02bc0aea793008d8bb37755Will Drewry state.last_time = RECENT_COMPILE_DATE + 1; 569c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 570c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Save and announce the initial time source. */ 571c45952f88c568046a02bc0aea793008d8bb37755Will Drewry trigger_event (&state, E_SAVE, -1); 572e11d02fe1d54baaf2bd1a5f98942455553f453f8Jacob Appelbaum verb ("tlsdated parasitic time synchronization initialized"); 573c45952f88c568046a02bc0aea793008d8bb37755Will Drewry info ("initial time sync type: %s", sync_type_str (state.last_sync_type)); 574c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Initialize platform specific loop behavior */ 575c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (platform_init_cros (&state)) 576c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 577c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to initialize platform code"); 578c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 579c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 580c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_event_route_up (&state)) 581c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 582c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to setup route up monitoring"); 583c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 584c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 585c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_event_timer_sync (&state)) 586c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 587c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to setup a timer event"); 588c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 589c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 590c45952f88c568046a02bc0aea793008d8bb37755Will Drewry if (setup_event_timer_continuity (&state)) 591c45952f88c568046a02bc0aea793008d8bb37755Will Drewry { 592c45952f88c568046a02bc0aea793008d8bb37755Will Drewry error ("Failed to setup continuity timer"); 593c45952f88c568046a02bc0aea793008d8bb37755Will Drewry goto out; 594c45952f88c568046a02bc0aea793008d8bb37755Will Drewry } 595c45952f88c568046a02bc0aea793008d8bb37755Will Drewry /* Add a forced sync event to the event list. */ 596c45952f88c568046a02bc0aea793008d8bb37755Will Drewry action_kickoff_time_sync (-1, EV_TIMEOUT, &state); 597b4a96dff4173182b66155c55a2a64c18f93bcfc9Jacob Appelbaum verb ("Entering dispatch . . ."); 598c45952f88c568046a02bc0aea793008d8bb37755Will Drewry event_base_dispatch (base); 599c79e118e77fe6a9964964c5782330b9b4ebf5ab5Jacob Appelbaum verb ("tlsdated event dispatch terminating gracefully"); 600c45952f88c568046a02bc0aea793008d8bb37755Will Drewryout: 601c45952f88c568046a02bc0aea793008d8bb37755Will Drewry return cleanup_main (&state); 6026fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones} 6036fb0d4b062af22e3576b8c48027710d10d764e34Elly Fong-Jones#endif /* !TLSDATED_MAIN */ 604