aboutsummaryrefslogtreecommitdiff
path: root/src/tlsdate.h
blob: 97d4fec429519286721c6df91ca2390a8563cd83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/* 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 <limits.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>

#include "src/rtc.h"

#define DEFAULT_HOST "google.com"
#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
/* 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 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

/** GNU/Hurd support requires that we declare this ourselves: */
#ifndef PATH_MAX
#define PATH_MAX 1024
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN PATH_MAX
#endif

struct source
{
	struct source *next;
	char *host;
	char *port;
	char *proxy;
	int id;
};

struct opts
{
  const char *user;
  const char *group;
  char *supp_groups;
  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;
  int leap;
  int should_dbus;
};

#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];
  struct rtc_handle hwclock;
  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;
};

char timestamp_path[PATH_MAX];

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);

void sync_and_save (void *hwclock_handle, int should_save);

/** This is where we store parsed commandline options. */
typedef struct
{
  int verbose;
  int verbose_debug;
  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 */