blob: c118d89478a212250c626b5fb6e6759edb439a78 [file] [log] [blame]
/* Copyright (c) 2013, Jacob Appelbaum
* Copyright (c) 2012, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file tlsdate.h
* \brief The main header for our clock helper.
**/
#ifndef TLSDATE_H
#define TLSDATE_H
#include "src/configmake.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <limits.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>
#define DEFAULT_HOST "www.ptb.de"
#define DEFAULT_PORT "443"
#define DEFAULT_PROXY "none"
#define DEFAULT_PROTOCOL "tlsv1"
#define DEFAULT_CERTDIR "/etc/ssl/certs"
#define DEFAULT_CERTFILE TLSDATE_CERTFILE
#define DEFAULT_DAEMON_CACHEDIR "/var/cache/tlsdated"
#define DEFAULT_DAEMON_TMPSUFFIX ".new"
#define DEFAULT_TLSDATE TLSDATE
#define DEFAULT_RTC_DEVICE "/dev/rtc"
#define DEFAULT_CONF_FILE TLSDATE_CONF_DIR "tlsdated.conf"
/* tlsdated magic numbers */
#define MAX_TRIES 10
#define WAIT_BETWEEN_TRIES 10
#define SUBPROCESS_TRIES 10
#define SUBPROCESS_WAIT_BETWEEN_TRIES 10
#define RESOLVER_TIMEOUT 30
#define ADJTIME_THRESHOLD 30
/* Invalidate the network sync once per day. */
#define STEADY_STATE_INTERVAL (60*60*24)
/* Check if the clock has jumped every four hours. */
#define CONTINUITY_INTERVAL (60*60*4)
#define DEFAULT_SYNC_HWCLOCK 1
#define DEFAULT_LOAD_FROM_DISK 1
#define DEFAULT_SAVE_TO_DISK 1
#define DEFAULT_USE_NETLINK 1
#define DEFAULT_DRY_RUN 0
#define MAX_SANE_BACKOFF (10*60) /* exponential backoff should only go this far */
#ifndef TLSDATED_MAX_DATE
#define TLSDATED_MAX_DATE 1999991337L /* this'll be a great bug some day */
#endif
#define MAX_EVENT_PRIORITIES 2
#define PRI_SAVE 0
#define PRI_NET 1
#define PRI_WAKE 1
#define PRI_ANY 1
/* Sync sources in order of "reliability" */
#define SYNC_TYPE_NONE (0)
#define SYNC_TYPE_BUILD (1 << 0)
#define SYNC_TYPE_DISK (1 << 1)
#define SYNC_TYPE_RTC (1 << 2)
#define SYNC_TYPE_PLATFORM (1 << 3)
#define SYNC_TYPE_NET (1 << 4)
/* Simple time setter<>tlsdated protocol */
#define SETTER_EXIT 0
#define SETTER_BAD_TIME 1
#define SETTER_NO_SAVE 2
#define SETTER_READ_ERR 3
#define SETTER_TIME_SET 4
#define SETTER_SET_ERR 5
#define SETTER_NO_SBOX 6
#define SETTER_NO_RTC 7
#define SETTER_GETTIME_ERR 8
#define TEST_HOST 'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', \
'c', 'o', 'm'
#define TEST_HOST_SIZE 14
static const char kTestHost[] = { TEST_HOST, 0 };
#define TEST_PORT 80
/** The current version of tlsdate. */
#define tlsdate_version VERSION
struct source
{
struct source *next;
char *host;
char *port;
char *proxy;
int id;
};
struct opts
{
const char *user;
const char *group;
int max_tries;
int min_steady_state_interval;
int wait_between_tries;
int subprocess_tries;
int subprocess_wait_between_tries;
int steady_state_interval;
int continuity_interval;
const char *base_path;
char **base_argv;
char **argv;
int should_sync_hwclock;
int should_load_disk;
int should_save_disk;
int should_netlink;
int dry_run;
int jitter;
char *conf_file;
struct source *sources;
struct source *cur_source;
char *proxy;
};
#define MAX_FQDN_LEN 255
#define MAX_SCHEME_LEN 9
#define MAX_PORT_LEN 6 /* incl. : */
#define MAX_PROXY_URL (MAX_FQDN_LEN + MAX_SCHEME_LEN + MAX_PORT_LEN + 1)
enum event_id_t
{
E_RESOLVER = 0,
E_TLSDATE,
E_TLSDATE_STATUS,
E_TLSDATE_TIMEOUT,
E_SAVE,
E_SIGCHLD,
E_SIGTERM,
E_STEADYSTATE,
E_ROUTEUP,
E_MAX
};
struct event_base;
/* This struct is used for passing tlsdated runtime state between
* events/ in its event loop.
*/
struct state
{
struct opts opts;
struct event_base *base;
void *dbus;
char **envp;
time_t clock_delta;
int last_sync_type;
time_t last_time;
char timestamp_path[PATH_MAX];
int hwclock_fd;
char dynamic_proxy[MAX_PROXY_URL];
/* Event triggered events */
struct event *events[E_MAX];
int tlsdate_monitor_fd;
pid_t tlsdate_pid;
pid_t setter_pid;
int setter_save_fd;
int setter_notify_fd;
uint32_t backoff;
int tries;
int resolving;
int running; /* tlsdate itself */
int exitting;
};
int is_sane_time (time_t ts);
int load_disk_timestamp (const char *path, time_t * t);
void save_disk_timestamp (const char *path, time_t t);
int add_jitter (int base, int jitter);
void time_setter_coprocess (int time_fd, int notify_fd, struct state *state);
int tlsdate (struct state *state);
int save_timestamp_to_fd (int fd, time_t t);
void set_conf_defaults (struct opts *opts);
int new_tlsdate_monitor_pipe (int fds[2]);
int read_tlsdate_response (int fd, time_t *t);
void invalidate_time (struct state *state);
int check_continuity (time_t *delta);
void action_check_continuity (int fd, short what, void *arg);
void action_kickoff_time_sync (int fd, short what, void *arg);
void action_invalidate_time (int fd, short what, void *arg);
void action_stdin_wakeup (int fd, short what, void *arg);
void action_netlink_ready (int fd, short what, void *arg);
void action_run_tlsdate (int fd, short what, void *arg);
void action_sigterm (int fd, short what, void *arg);
void action_sync_and_save (int fd, short what, void *arg);
void action_time_set (int fd, short what, void *arg);
void action_tlsdate_status (int fd, short what, void *arg);
int setup_event_timer_continuity (struct state *state);
int setup_event_timer_sync (struct state *state);
int setup_event_route_up (struct state *state);
int setup_time_setter (struct state *state);
int setup_tlsdate_status (struct state *state);
int setup_sigchld_event (struct state *state, int persist);
void report_setter_error (siginfo_t *info);
/** This is where we store parsed commandline options. */
typedef struct
{
int verbose;
int ca_racket;
int help;
int showtime;
int setclock;
time_t manual_time;
char *host;
char *port;
char *protocol;
} tlsdate_options_t;
#endif /* TLSDATE_H */