1/* Copyright (c) 2012, Jacob Appelbaum.
2 * Copyright (c) 2012, The Tor Project, Inc.
3 * Copyright (c) 2012, Christian Grothoff. */
4/* See LICENSE for licensing information */
5/*
6                    This file contains the license for tlsdate,
7        a free software project to set your system clock securely.
8
9        It also lists the licenses for other components used by tlsdate.
10
11      For more information about tlsdate, see https://github.com/ioerror/tlsdate
12
13             If you got this file as a part of a larger bundle,
14        there may be other license terms that you should be aware of.
15
16===============================================================================
17tlsdate is distributed under this license:
18
19Copyright (c) 2011-2012, Jacob Appelbaum <jacob@appelbaum.net>
20Copyright (c) 2011-2012, The Tor Project, Inc.
21
22Redistribution and use in source and binary forms, with or without
23modification, are permitted provided that the following conditions are
24met:
25
26    * Redistributions of source code must retain the above copyright
27notice, this list of conditions and the following disclaimer.
28
29    * Redistributions in binary form must reproduce the above
30copyright notice, this list of conditions and the following disclaimer
31in the documentation and/or other materials provided with the
32distribution.
33
34    * Neither the names of the copyright owners nor the names of its
35contributors may be used to endorse or promote products derived from
36this software without specific prior written permission.
37
38THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
41A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
42OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49===============================================================================
50If you got tlsdate as a static binary with OpenSSL included, then you should
51know:
52
53 "This product includes software developed by the OpenSSL Project for use in
54  the OpenSSL Toolkit (http://www.openssl.org/)"
55
56===============================================================================
57*/
58
59/**
60 * \file tlsdate-helper.c
61 * \brief Helper program that does the actual work of setting the system clock.
62 **/
63
64/*
65 * tlsdate is a tool for setting the system clock by hand or by communication
66 * with the network. It does not set the RTC. It is designed to be as secure as
67 * TLS (RFC 2246) but of course the security of TLS is often reduced to
68 * whichever CA racket you believe is trustworthy. By default, tlsdate trusts
69 * your local CA root store - so any of these companies could assist in a MITM
70 * attack against you and you'd be screwed.
71
72 * This tool is designed to be run by hand or as a system daemon. It must be
73 * run as root or otherwise have the proper caps; it will not be able to set
74 * the system time without running as root or another privileged user.
75 */
76
77#include "config.h"
78#include "src/tlsdate-helper.h"
79#include "src/util.h"
80
81#ifndef USE_POLARSSL
82#include "src/proxy-bio.h"
83#else
84#include "src/proxy-polarssl.h"
85#endif
86
87#include "src/compat/clock.h"
88
89#ifndef MAP_ANONYMOUS
90#define MAP_ANONYMOUS MAP_ANON
91#endif
92
93#ifdef USE_POLARSSL
94#include "polarssl/entropy.h"
95#include "polarssl/ctr_drbg.h"
96#include "polarssl/ssl.h"
97#endif
98
99static void
100validate_proxy_scheme(const char *scheme)
101{
102  if (!strcmp(scheme, "http"))
103    return;
104  if (!strcmp(scheme, "socks4"))
105    return;
106  if (!strcmp(scheme, "socks5"))
107    return;
108  die("invalid proxy scheme");
109}
110
111static void
112validate_proxy_host(const char *host)
113{
114  const char *kValid = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
115                       "abcdefghijklmnopqrstuvwxyz"
116                       "0123456789"
117                       ".-";
118  if (strspn(host, kValid) != strlen(host))
119    die("invalid char in host");
120}
121
122static void
123validate_proxy_port(const char *port)
124{
125  while (*port)
126    if (!isdigit((int)(unsigned char)*port++))
127      die("invalid char in port");
128}
129
130static void
131parse_proxy_uri(char *proxy, char **scheme, char **host, char **port)
132{
133  /* Expecting a URI, so: <scheme> '://' <host> ':' <port> */
134  *scheme = proxy;
135  proxy = strstr(proxy, "://");
136  if (!proxy)
137    die("malformed proxy URI");
138  *proxy = '\0'; /* terminate scheme string */
139  proxy += strlen("://");
140
141  *host = proxy;
142  proxy = strchr(proxy, ':');
143  if (!proxy)
144    die("malformed proxy URI");
145  *proxy++ = '\0';
146
147  *port = proxy;
148
149  validate_proxy_scheme(*scheme);
150  validate_proxy_host(*host);
151  validate_proxy_port(*port);
152}
153
154#ifndef USE_POLARSSL
155static void
156setup_proxy(BIO *ssl)
157{
158  BIO *bio;
159  char *scheme;
160  char *proxy_host;
161  char *proxy_port;
162
163  if (!proxy)
164    return;
165  /*
166   * grab the proxy's host and port out of the URI we have for it. We want the
167   * underlying connect BIO to connect to this, not the target host and port, so
168   * we squirrel away the target host and port in the proxy BIO (as the proxy
169   * target) and swap out the connect BIO's target host and port so it'll
170   * connect to the proxy instead.
171   */
172  parse_proxy_uri(proxy, &scheme, &proxy_host, &proxy_port);
173  bio = BIO_new_proxy();
174  BIO_proxy_set_type(bio, scheme);
175  BIO_proxy_set_host(bio, host);
176  BIO_proxy_set_port(bio, atoi(port));
177  host = proxy_host;
178  port = proxy_port;
179  BIO_push(ssl, bio);
180}
181
182static int
183write_all_to_ssl(SSL *ssl, const char *string)
184{
185  int n = (int) strlen(string);
186  int r;
187
188  while (n) {
189    r = SSL_write(ssl, string, n);
190    if (r > 0) {
191      if (r > n)
192        return -1;
193      n -= r;
194      string += r;
195    } else {
196      return 0;
197    }
198  }
199
200  return 1;
201}
202
203/* If the string is all nice clean ascii that it's safe to log, return
204 * it. Otherwise return a placeholder "This is junk" string. */
205static const char *
206sanitize_string(const char *s)
207{
208  const unsigned char *cp;
209  for (cp = (const unsigned char *)s; *cp; cp++) {
210    if (*cp < 32 || *cp >= 127)
211      return "string with invalid characters";
212  }
213  return s;
214}
215
216static int
217handle_date_line(const char *dateline, uint32_t *result)
218{
219  int year,mon,day,hour,min,sec;
220  char month[4];
221  struct tm tm;
222  int i;
223  time_t t;
224  /* We recognize the three formats in RFC2616, section 3.3.1.  Month
225     names are always in English.  The formats are:
226
227      Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
228      Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
229      Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
230
231     Note that the first is preferred.
232   */
233
234  static const char *MONTHS[] =
235    { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
236      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
237
238  if (strncmp("\r\nDate: ", dateline, 8))
239    return 0;
240
241  dateline += 8;
242  if (strlen(dateline) > MAX_DATE_LINE_LEN) {
243    verb("V: The date line was impossibly long.");
244    return -1;
245  }
246  verb("V: The alleged date is <%s>", sanitize_string(dateline));
247
248  while (*dateline == ' ')
249    ++dateline;
250  while (*dateline && *dateline != ' ')
251    ++dateline;
252  while (*dateline == ' ')
253    ++dateline;
254  /* We just skipped over the day of the week. Now we have:*/
255  if (sscanf(dateline, "%d %3s %d %d:%d:%d",
256             &day, month, &year, &hour, &min, &sec) == 6 ||
257      sscanf(dateline, "%d-%3s-%d %d:%d:%d",
258             &day, month, &year, &hour, &min, &sec) == 6 ||
259      sscanf(dateline, "%3s %d %d:%d:%d %d",
260             month, &day, &hour, &min, &sec, &year) == 6) {
261
262    /* Two digit dates are defined to be relative to 1900; all other dates
263     * are supposed to be represented as four digits. */
264    if (year < 100)
265      year += 1900;
266
267    verb("V: Parsed the date: %04d-%s-%02d %02d:%02d:%02d",
268         year, month, day, hour, min, sec);
269  } else {
270    verb("V: Couldn't parse date.");
271    return -1;
272  }
273
274  for (i = 0; ; ++i) {
275    if (!MONTHS[i])
276      return -2;
277    if (!strcmp(month, MONTHS[i])) {
278      mon = i;
279      break;
280    }
281  }
282
283  memset(&tm, 0, sizeof(tm));
284  tm.tm_year = year - 1900;
285  tm.tm_mon = mon;
286  tm.tm_mday = day;
287  tm.tm_hour = hour;
288  tm.tm_min = min;
289  tm.tm_sec = sec;
290
291  t = timegm(&tm);
292  if (t > ((time_t) 0xffffffff) || t < 0)
293    return -1;
294
295  *result = (uint32_t) t;
296
297  return 1;
298}
299
300static int
301read_http_date_from_ssl(SSL *ssl, uint32_t *result)
302{
303  int n;
304  char buf[MAX_HTTP_HEADERS_SIZE];
305  size_t buf_len=0;
306  char *dateline, *endofline;
307
308  while (buf_len < sizeof(buf)-1) {
309    n = SSL_read(ssl, buf+buf_len, sizeof(buf)-buf_len-1);
310    if (n <= 0)
311      return 0;
312    buf_len += n;
313    buf[buf_len] = 0;
314    verb_debug ("V: read %d bytes.", n, buf);
315
316    dateline = memmem(buf, buf_len, "\r\nDate: ", 8);
317    if (NULL == dateline)
318      continue;
319
320    endofline = memmem(dateline+2, buf_len - (dateline-buf+2), "\r\n", 2);
321    if (NULL == endofline)
322      continue;
323
324    *endofline = 0;
325    return handle_date_line(dateline, result);
326  }
327  return -2;
328}
329
330/** helper function for 'malloc' */
331static void *
332xmalloc (size_t size)
333{
334  void *ptr;
335
336  if (0 == size)
337    die("xmalloc: zero size");
338
339  ptr = malloc(size);
340  if (NULL == ptr)
341    die("xmalloc: out of memory (allocating %zu bytes)", size);
342
343  return ptr;
344}
345
346
347/** helper function for 'free' */
348static void
349xfree (void *ptr)
350{
351  if (NULL == ptr)
352    die("xfree: NULL pointer given as argument");
353
354  free(ptr);
355}
356
357void
358openssl_time_callback (const SSL* ssl, int where, int ret)
359{
360  if (where == SSL_CB_CONNECT_LOOP &&
361      (ssl->state == SSL3_ST_CR_SRVR_HELLO_A || ssl->state == SSL3_ST_CR_SRVR_HELLO_B))
362  {
363    // XXX TODO: If we want to trust the remote system for time,
364    // can we just read that time out of the remote system and if the
365    // cert verifies, decide that the time is reasonable?
366    // Such a process seems to indicate that a once valid cert would be
367    // forever valid - we stopgap that by ensuring it isn't less than
368    // the latest compiled_time and isn't above max_reasonable_time...
369    // XXX TODO: Solve eternal question about the Chicken and the Egg...
370    uint32_t compiled_time = RECENT_COMPILE_DATE;
371    uint32_t max_reasonable_time = MAX_REASONABLE_TIME;
372    uint32_t server_time;
373    verb("V: freezing time for x509 verification");
374    memcpy(&server_time, ssl->s3->server_random, sizeof(uint32_t));
375    if (compiled_time < ntohl(server_time)
376        &&
377        ntohl(server_time) < max_reasonable_time)
378    {
379      verb("V: remote peer provided: %d, preferred over compile time: %d",
380            ntohl(server_time), compiled_time);
381      verb("V: freezing time with X509_VERIFY_PARAM_set_time");
382      X509_VERIFY_PARAM_set_time(ssl->ctx->cert_store->param,
383                                 (time_t) ntohl(server_time) + 86400);
384    } else {
385      die("V: the remote server is a false ticker! server: %d compile: %d",
386           ntohl(server_time), compiled_time);
387    }
388  }
389}
390
391static const char *
392key_type_to_str (int key_type)
393{
394  switch (key_type)
395  {
396    case EVP_PKEY_RSA:
397      return "EVP_PKEY_RSA";
398    case EVP_PKEY_RSA2:
399      return "EVP_PKEY_RSA2";
400    case EVP_PKEY_DSA:
401      return "EVP_PKEY_DSA";
402#if defined(EVP_PKEY_DSA1)
403    case EVP_PKEY_DSA1:
404      return "EVP_PKEY_DSA1";
405#endif  /* EVP_PKEY_DSA1 */
406#if defined(EVP_PKEY_DSA2)
407    case EVP_PKEY_DSA2:
408      return "EVP_PKEY_DSA2";
409#endif  /* EVP_PKEY_DSA2 */
410#if defined(EVP_PKEY_DSA3)
411    case EVP_PKEY_DSA3:
412      return "EVP_PKEY_DSA3";
413#endif  /* EVP_PKEY_DSA3 */
414#if defined(EVP_PKEY_DSA4)
415    case EVP_PKEY_DSA4:
416      return "EVP_PKEY_DSA4";
417#endif  /* EVP_PKEY_DSA4 */
418    case EVP_PKEY_DH:
419      return "EVP_PKEY_DH";
420    case EVP_PKEY_EC:
421      return "EVP_PKEY_EC";
422    // Should we also care about EVP_PKEY_HMAC and EVP_PKEY_CMAC?
423    default:
424      return NULL;
425  }
426  return NULL;
427}
428
429uint32_t
430get_certificate_keybits (EVP_PKEY *public_key)
431{
432  /*
433    In theory, we could use check_bitlen_dsa() and check_bitlen_rsa()
434   */
435  uint32_t key_bits;
436  const char *key_type_str;
437
438  key_type_str = key_type_to_str(public_key->type);
439  if (key_type_str)
440    verb("V: key type: %s", key_type_str);
441  else
442    verb("V: key type: %d", public_key->type);
443
444  key_bits = EVP_PKEY_bits(public_key);
445  if (0 == key_bits)
446    die ("unknown public key type");
447  verb ("V: keybits: %d", key_bits);
448  return key_bits;
449}
450
451uint32_t
452dns_label_count(char *label, char *delim)
453{
454  char *label_tmp;
455  char *saveptr;
456  char *saveptr_tmp;
457  uint32_t label_count;
458
459  label_tmp = strdup(label);
460  label_count = 0;
461  saveptr = NULL;
462  saveptr_tmp = NULL;
463  saveptr = strtok_r(label_tmp, delim, &saveptr);
464  if (NULL != saveptr)
465  {
466    // Did we find our first label?
467    if (saveptr[0] != delim[0])
468    {
469      label_count++;
470    }
471    do
472    {
473      // Find all subsequent labels
474      label_count++;
475      saveptr_tmp = strtok_r(NULL, delim, &saveptr);
476    } while (NULL != saveptr_tmp);
477  }
478  verb_debug ("V: label found; total label count: %d", label_count);
479  free(label_tmp);
480  return label_count;
481}
482
483// first we split strings on '.'
484// then we call each split string a 'label'
485// Do not allow '*' for the top level domain label; eg never allow *.*.com
486// Do not allow '*' for subsequent subdomains; eg never allow *.foo.example.com
487// Do allow *.example.com
488uint32_t
489check_wildcard_match_rfc2595 (const char *orig_hostname,
490                      const char *orig_cert_wild_card)
491{
492  char *hostname;
493  char *hostname_to_free;
494  char *cert_wild_card;
495  char *cert_wild_card_to_free;
496  char *expected_label;
497  char *wildcard_label;
498  char *delim;
499  char *wildchar;
500  uint32_t ok;
501  uint32_t wildcard_encountered;
502  uint32_t label_count;
503
504  // First we copy the original strings
505  hostname = strndup(orig_hostname, strlen(orig_hostname));
506  cert_wild_card = strndup(orig_cert_wild_card, strlen(orig_cert_wild_card));
507  hostname_to_free = hostname;
508  cert_wild_card_to_free = cert_wild_card;
509  delim = strdup(".");
510  wildchar = strdup("*");
511
512  verb_debug ("V: Inspecting '%s' for possible wildcard match against '%s'",
513         hostname, cert_wild_card);
514
515  // By default we have not processed any labels
516  label_count = dns_label_count(cert_wild_card, delim);
517
518  // By default we have no match
519  ok = 0;
520  wildcard_encountered = 0;
521  // First - do we have labels? If not, we refuse to even try to match
522  if ((NULL != strpbrk(cert_wild_card, delim)) &&
523      (NULL != strpbrk(hostname, delim)) &&
524      (label_count <= ((uint32_t)RFC2595_MIN_LABEL_COUNT)))
525  {
526    if (wildchar[0] == cert_wild_card[0])
527    {
528      verb_debug ("V: Found wildcard in at start of provided certificate name");
529      do
530      {
531        // Skip over the bytes between the first char and until the next label
532        wildcard_label = strsep(&cert_wild_card, delim);
533        expected_label = strsep(&hostname, delim);
534        if (NULL != wildcard_label &&
535            NULL != expected_label &&
536            NULL != hostname &&
537            NULL != cert_wild_card)
538        {
539          // Now we only consider this wildcard valid if the rest of the
540          // hostnames match verbatim
541          verb_debug ("V: Attempting match of '%s' against '%s'",
542                 expected_label, wildcard_label);
543          // This is the case where we have a label that begins with wildcard
544          // Furthermore, we only allow this for the first label
545          if (wildcard_label[0] == wildchar[0] &&
546              0 == wildcard_encountered && 0 == ok)
547          {
548            verb ("V: Forced match of '%s' against '%s'", expected_label, wildcard_label);
549            wildcard_encountered = 1;
550          } else {
551            verb_debug ("V: Attempting match of '%s' against '%s'",
552                   hostname, cert_wild_card);
553            if (0 == strcasecmp (expected_label, wildcard_label) &&
554                label_count >= ((uint32_t)RFC2595_MIN_LABEL_COUNT))
555            {
556              ok = 1;
557              verb_debug ("V: remaining labels match!");
558              break;
559            } else {
560              ok = 0;
561              verb_debug ("V: remaining labels do not match!");
562              break;
563            }
564          }
565        } else {
566          // We hit this case when we have a mismatched number of labels
567          verb_debug ("V: NULL label; no wildcard here");
568          break;
569        }
570      } while (0 != wildcard_encountered && label_count <= RFC2595_MIN_LABEL_COUNT);
571    } else {
572      verb_debug ("V: Not a RFC 2595 wildcard");
573    }
574  } else {
575    verb_debug ("V: Not a valid wildcard certificate");
576    ok = 0;
577  }
578  // Free our copies
579  free(wildchar);
580  free(delim);
581  free(hostname_to_free);
582  free(cert_wild_card_to_free);
583  if (wildcard_encountered & ok && label_count >= RFC2595_MIN_LABEL_COUNT)
584  {
585    verb_debug ("V: wildcard match of %s against %s",
586          orig_hostname, orig_cert_wild_card);
587    return (wildcard_encountered & ok);
588  } else {
589    verb_debug ("V: wildcard match failure of %s against %s",
590          orig_hostname, orig_cert_wild_card);
591    return 0;
592  }
593}
594#endif
595
596#ifndef USE_POLARSSL
597/**
598 This extracts the first commonName and checks it against hostname.
599*/
600uint32_t
601check_cn (SSL *ssl, const char *hostname)
602{
603  int ok = 0;
604  int ret;
605  char *cn_buf;
606  X509 *certificate;
607  X509_NAME *xname;
608
609  // We cast this to cast away g++ complaining about the following:
610  // error: invalid conversion from ‘void*’ to ‘char*’
611  cn_buf = (char *) xmalloc(TLSDATE_HOST_NAME_MAX + 1);
612
613  certificate = SSL_get_peer_certificate(ssl);
614  if (NULL == certificate)
615  {
616    die ("Unable to extract certificate");
617  }
618
619  memset(cn_buf, '\0', (TLSDATE_HOST_NAME_MAX + 1));
620  xname = X509_get_subject_name(certificate);
621  ret = X509_NAME_get_text_by_NID(xname, NID_commonName,
622                                  cn_buf, TLSDATE_HOST_NAME_MAX);
623
624  if (-1 == ret || ret != (int) strlen(cn_buf))
625  {
626    die ("Unable to extract commonName");
627  }
628  if (strcasecmp(cn_buf, hostname))
629  {
630    verb ("V: commonName mismatch! Expected: %s - received: %s",
631          hostname, cn_buf);
632  } else {
633    verb ("V: commonName matched: %s", cn_buf);
634    ok = 1;
635  }
636
637  X509_NAME_free(xname);
638  X509_free(certificate);
639  xfree(cn_buf);
640
641  return ok;
642}
643
644/**
645 Search for a hostname match in the SubjectAlternativeNames.
646*/
647uint32_t
648check_san (SSL *ssl, const char *hostname)
649{
650  X509 *cert;
651  int extcount, ok = 0;
652  /* What an OpenSSL mess ... */
653  if (NULL == (cert = SSL_get_peer_certificate(ssl)))
654  {
655    die ("Getting certificate failed");
656  }
657
658  if ((extcount = X509_get_ext_count(cert)) > 0)
659  {
660    int i;
661    for (i = 0; i < extcount; ++i)
662    {
663      const char *extstr;
664      X509_EXTENSION *ext;
665      ext = X509_get_ext(cert, i);
666      extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
667
668      if (!strcmp(extstr, "subjectAltName"))
669      {
670
671        int j;
672        void *extvalstr;
673        const unsigned char *tmp;
674
675        STACK_OF(CONF_VALUE) *val;
676        CONF_VALUE *nval;
677#if OPENSSL_VERSION_NUMBER >= 0x10000000L
678        const
679#endif
680        X509V3_EXT_METHOD *method;
681
682        if (!(method = X509V3_EXT_get(ext)))
683        {
684          break;
685        }
686
687        tmp = ext->value->data;
688        if (method->it)
689        {
690          extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length,
691                                    ASN1_ITEM_ptr(method->it));
692        } else {
693          extvalstr = method->d2i(NULL, &tmp, ext->value->length);
694        }
695
696        if (!extvalstr)
697        {
698          break;
699        }
700
701        if (method->i2v)
702        {
703          val = method->i2v(method, extvalstr, NULL);
704          for (j = 0; ((size_t) j) < sk_CONF_VALUE_num(val); ++j)
705          {
706            nval = sk_CONF_VALUE_value(val, j);
707            if ((!strcasecmp(nval->name, "DNS") &&
708                !strcasecmp(nval->value, hostname) ) ||
709                (!strcasecmp(nval->name, "iPAddress") &&
710                !strcasecmp(nval->value, hostname)))
711            {
712              verb ("V: subjectAltName matched: %s, type: %s", nval->value, nval->name); // We matched this; so it's safe to print
713              ok = 1;
714              break;
715            }
716            // Attempt to match subjectAltName DNS names
717            if (!strcasecmp(nval->name, "DNS"))
718            {
719              ok = check_wildcard_match_rfc2595(hostname, nval->value);
720              if (ok)
721              {
722                break;
723              }
724            }
725            verb_debug ("V: subjectAltName found but not matched: %s, type: %s",
726                nval->value, sanitize_string(nval->name));
727          }
728        }
729      } else {
730        verb_debug ("V: found non subjectAltName extension");
731      }
732      if (ok)
733      {
734        break;
735      }
736    }
737  } else {
738    verb_debug ("V: no X509_EXTENSION field(s) found");
739  }
740  X509_free(cert);
741  return ok;
742}
743
744uint32_t
745check_name (SSL *ssl, const char *hostname)
746{
747  uint32_t ret;
748  ret = check_cn(ssl, hostname);
749  ret += check_san(ssl, hostname);
750  if (0 != ret && 0 < ret)
751  {
752    verb ("V: hostname verification passed");
753  } else {
754    die ("hostname verification failed for host %s!", host);
755  }
756  return ret;
757}
758#endif
759
760#ifdef USE_POLARSSL
761uint32_t
762verify_signature (ssl_context *ssl, const char *hostname)
763{
764  int ssl_verify_result;
765
766  ssl_verify_result = ssl_get_verify_result (ssl);
767  if (ssl_verify_result & BADCERT_EXPIRED)
768  {
769    die ("certificate has expired");
770  }
771  if (ssl_verify_result & BADCERT_REVOKED)
772  {
773    die ("certificate has been revoked");
774  }
775  if (ssl_verify_result & BADCERT_CN_MISMATCH)
776  {
777    die ("CN and subject AltName mismatch for certificate");
778  }
779  if (ssl_verify_result & BADCERT_NOT_TRUSTED)
780  {
781    die ("certificate is self-signed or not signed by a trusted CA");
782  }
783
784  if (0 == ssl_verify_result)
785  {
786    verb ("V: verify success");
787  }
788  else
789  {
790    die ("certificate verification error: -0x%04x", -ssl_verify_result);
791  }
792  return 0;
793}
794#else
795uint32_t
796verify_signature (SSL *ssl, const char *hostname)
797{
798  long ssl_verify_result;
799  X509 *certificate;
800
801  certificate = SSL_get_peer_certificate(ssl);
802  if (NULL == certificate)
803  {
804    die ("Getting certificate failed");
805  }
806  // In theory, we verify that the cert is valid
807  ssl_verify_result = SSL_get_verify_result(ssl);
808  switch (ssl_verify_result)
809  {
810  case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
811  case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
812    die ("certificate is self signed");
813  case X509_V_OK:
814    verb ("V: certificate verification passed");
815    break;
816  default:
817    die ("certification verification error: %ld",
818         ssl_verify_result);
819  }
820 return 0;
821}
822#endif
823
824#ifdef USE_POLARSSL
825void
826check_key_length (ssl_context *ssl)
827{
828  uint32_t key_bits;
829  const x509_cert *certificate;
830  const rsa_context *public_key;
831  char buf[1024];
832
833  certificate = ssl_get_peer_cert (ssl);
834  if (NULL == certificate)
835  {
836    die ("Getting certificate failed");
837  }
838
839  x509parse_dn_gets(buf, 1024, &certificate->subject);
840  verb_debug ("V: Certificate for subject '%s'", buf);
841
842  public_key = &certificate->rsa;
843  if (NULL == public_key)
844  {
845    die ("public key extraction failure");
846  } else {
847    verb_debug ("V: public key is ready for inspection");
848  }
849  key_bits = mpi_msb (&public_key->N);
850  if (MIN_PUB_KEY_LEN >= key_bits)
851  {
852    die ("Unsafe public key size: %d bits", key_bits);
853  } else {
854    verb_debug ("V: key length appears safe");
855  }
856}
857#else
858void
859check_key_length (SSL *ssl)
860{
861  uint32_t key_bits;
862  X509 *certificate;
863  EVP_PKEY *public_key;
864  certificate = SSL_get_peer_certificate (ssl);
865  if (NULL == certificate)
866  {
867    die ("Getting certificate failed");
868  }
869  public_key = X509_get_pubkey (certificate);
870  if (NULL == public_key)
871  {
872    die ("public key extraction failure");
873  } else {
874    verb_debug ("V: public key is ready for inspection");
875  }
876
877  key_bits = get_certificate_keybits (public_key);
878  if (MIN_PUB_KEY_LEN >= key_bits && public_key->type != EVP_PKEY_EC)
879  {
880    die ("Unsafe public key size: %d bits", key_bits);
881  } else {
882     if (public_key->type == EVP_PKEY_EC)
883       if(key_bits >= MIN_ECC_PUB_KEY_LEN
884          && key_bits <= MAX_ECC_PUB_KEY_LEN)
885       {
886         verb_debug ("V: ECC key length appears safe");
887       } else {
888         die ("Unsafe ECC key size: %d bits", key_bits);
889     } else {
890       verb_debug ("V: key length appears safe");
891     }
892  }
893  EVP_PKEY_free (public_key);
894}
895#endif
896
897#ifdef USE_POLARSSL
898void
899inspect_key (ssl_context *ssl, const char *hostname)
900{
901  verify_signature (ssl, hostname);
902
903  // ssl_get_verify_result() already checks for CN / subjectAltName match
904  // and reports the mismatch as error. So check_name() is not called
905}
906#else
907void
908inspect_key (SSL *ssl, const char *hostname)
909{
910
911    verify_signature (ssl, hostname);
912    check_name (ssl, hostname);
913}
914#endif
915
916#ifdef USE_POLARSSL
917void
918check_timestamp (uint32_t server_time)
919{
920  uint32_t compiled_time = RECENT_COMPILE_DATE;
921  uint32_t max_reasonable_time = MAX_REASONABLE_TIME;
922  if (compiled_time < server_time
923      &&
924      server_time < max_reasonable_time)
925  {
926    verb("V: remote peer provided: %d, preferred over compile time: %d",
927          server_time, compiled_time);
928  } else {
929    die("V: the remote server is a false ticker! server: %d compile: %d",
930         server_time, compiled_time);
931  }
932}
933
934static int ssl_do_handshake_part(ssl_context *ssl)
935{
936  int ret = 0;
937
938  /* Only do steps till ServerHello is received */
939  while (ssl->state != SSL_SERVER_HELLO)
940  {
941    ret = ssl_handshake_step (ssl);
942    if (0 != ret)
943    {
944      die("SSL handshake failed");
945    }
946  }
947  /* Do ServerHello so we can skim the timestamp */
948  ret = ssl_handshake_step (ssl);
949  if (0 != ret)
950  {
951    die("SSL handshake failed");
952  }
953
954  return 0;
955}
956
957/**
958 * Run SSL handshake and store the resulting time value in the
959 * 'time_map'.
960 *
961 * @param time_map where to store the current time
962 * @param time_is_an_illusion
963 * @param http whether to do an http request and take the date from that
964 *     instead.
965 */
966static void
967run_ssl (uint32_t *time_map, int time_is_an_illusion, int http)
968{
969  entropy_context entropy;
970  ctr_drbg_context ctr_drbg;
971  ssl_context ssl;
972  proxy_polarssl_ctx proxy_ctx;
973  x509_cert cacert;
974  struct stat statbuf;
975  int ret = 0, server_fd = 0;
976  char *pers = "tlsdate-helper";
977
978  memset (&ssl, 0, sizeof(ssl_context));
979  memset (&cacert, 0, sizeof(x509_cert));
980
981  verb("V: Using PolarSSL for SSL");
982  if (ca_racket)
983  {
984    if (-1 == stat (ca_cert_container, &statbuf))
985    {
986      die("Unable to stat CA certficate container %s", ca_cert_container);
987    }
988    else
989    {
990      switch (statbuf.st_mode & S_IFMT)
991      {
992      case S_IFREG:
993        if (0 > x509parse_crtfile(&cacert, ca_cert_container))
994          fprintf(stderr, "x509parse_crtfile failed");
995        break;
996      case S_IFDIR:
997        if (0 > x509parse_crtpath(&cacert, ca_cert_container))
998          fprintf(stderr, "x509parse_crtpath failed");
999        break;
1000      default:
1001        die("Unable to load CA certficate container %s", ca_cert_container);
1002      }
1003    }
1004  }
1005
1006  entropy_init (&entropy);
1007  if (0 != ctr_drbg_init (&ctr_drbg, entropy_func, &entropy,
1008                         (unsigned char *) pers, strlen(pers)))
1009  {
1010    die("Failed to initialize CTR_DRBG");
1011  }
1012
1013  if (0 != ssl_init (&ssl))
1014  {
1015    die("SSL initialization failed");
1016  }
1017  ssl_set_endpoint (&ssl, SSL_IS_CLIENT);
1018  ssl_set_rng (&ssl, ctr_drbg_random, &ctr_drbg);
1019  ssl_set_ca_chain (&ssl, &cacert, NULL, hostname_to_verify);
1020  if (ca_racket)
1021  {
1022      // You can do SSL_VERIFY_REQUIRED here, but then the check in
1023      // inspect_key() never happens as the ssl_handshake() will fail.
1024      ssl_set_authmode (&ssl, SSL_VERIFY_OPTIONAL);
1025  }
1026
1027  if (proxy)
1028  {
1029    char *scheme;
1030    char *proxy_host;
1031    char *proxy_port;
1032
1033    parse_proxy_uri (proxy, &scheme, &proxy_host, &proxy_port);
1034
1035    verb("V: opening socket to proxy %s:%s", proxy_host, proxy_port);
1036    if (0 != net_connect (&server_fd, proxy_host, atoi(proxy_port)))
1037    {
1038      die ("SSL connection failed");
1039    }
1040
1041    proxy_polarssl_init (&proxy_ctx);
1042    proxy_polarssl_set_bio (&proxy_ctx, net_recv, &server_fd, net_send, &server_fd);
1043    proxy_polarssl_set_host (&proxy_ctx, host);
1044    proxy_polarssl_set_port (&proxy_ctx, atoi(port));
1045    proxy_polarssl_set_scheme (&proxy_ctx, scheme);
1046
1047    ssl_set_bio (&ssl, proxy_polarssl_recv, &proxy_ctx, proxy_polarssl_send, &proxy_ctx);
1048
1049    verb("V: Handle proxy connection");
1050    if (0 == proxy_ctx.f_connect (&proxy_ctx))
1051      die("Proxy connection failed");
1052  }
1053  else
1054  {
1055    verb("V: opening socket to %s:%s", host, port);
1056    if (0 != net_connect (&server_fd, host, atoi(port)))
1057    {
1058      die ("SSL connection failed");
1059    }
1060
1061    ssl_set_bio (&ssl, net_recv, &server_fd, net_send, &server_fd);
1062  }
1063
1064  verb("V: starting handshake");
1065  if (0 != ssl_do_handshake_part (&ssl))
1066    die("SSL handshake first part failed");
1067
1068  uint32_t timestamp = ( (uint32_t) ssl.in_msg[6] << 24 )
1069                     | ( (uint32_t) ssl.in_msg[7] << 16 )
1070                     | ( (uint32_t) ssl.in_msg[8] <<  8 )
1071                     | ( (uint32_t) ssl.in_msg[9]       );
1072  check_timestamp (timestamp);
1073
1074  verb("V: continuing handshake");
1075  /* Continue with handshake */
1076  while (0 != (ret = ssl_handshake (&ssl)))
1077  {
1078    if (POLARSSL_ERR_NET_WANT_READ  != ret &&
1079        POLARSSL_ERR_NET_WANT_WRITE != ret)
1080    {
1081      die("SSL handshake failed");
1082    }
1083  }
1084
1085  // Verify the peer certificate against the CA certs on the local system
1086  if (ca_racket) {
1087    inspect_key (&ssl, hostname_to_verify);
1088  } else {
1089    verb ("V: Certificate verification skipped!");
1090  }
1091  check_key_length (&ssl);
1092
1093  memcpy (time_map, &timestamp, sizeof(uint32_t));
1094  proxy_polarssl_free (&proxy_ctx);
1095  ssl_free (&ssl);
1096  x509_free (&cacert);
1097}
1098#else /* USE_POLARSSL */
1099/**
1100 * Run SSL handshake and store the resulting time value in the
1101 * 'time_map'.
1102 *
1103 * @param time_map where to store the current time
1104 * @param time_is_an_illusion
1105 * @param http whether to do an http request and take the date from that
1106 *     instead.
1107 */
1108static void
1109run_ssl (uint32_t *time_map, int time_is_an_illusion, int http)
1110{
1111  BIO *s_bio;
1112  SSL_CTX *ctx;
1113  SSL *ssl;
1114  struct stat statbuf;
1115  uint32_t result_time;
1116
1117  SSL_load_error_strings();
1118  SSL_library_init();
1119
1120  ctx = NULL;
1121  if (0 == strcmp("sslv23", protocol))
1122  {
1123    verb ("V: using SSLv23_client_method()");
1124    ctx = SSL_CTX_new(SSLv23_client_method());
1125  } else if (0 == strcmp("sslv3", protocol))
1126  {
1127    verb ("V: using SSLv3_client_method()");
1128    ctx = SSL_CTX_new(SSLv3_client_method());
1129  } else if (0 == strcmp("tlsv1", protocol))
1130  {
1131    verb ("V: using TLSv1_client_method()");
1132    ctx = SSL_CTX_new(TLSv1_client_method());
1133  } else
1134    die("Unsupported protocol `%s'", protocol);
1135
1136  if (ctx == NULL)
1137    die("OpenSSL failed to support protocol `%s'", protocol);
1138
1139  verb("V: Using OpenSSL for SSL");
1140  if (ca_racket)
1141  {
1142    if (-1 == stat(ca_cert_container, &statbuf))
1143    {
1144      die("Unable to stat CA certficate container %s", ca_cert_container);
1145    } else
1146    {
1147      switch (statbuf.st_mode & S_IFMT)
1148      {
1149      case S_IFREG:
1150        if (1 != SSL_CTX_load_verify_locations(ctx, ca_cert_container, NULL))
1151          fprintf(stderr, "SSL_CTX_load_verify_locations failed");
1152        break;
1153      case S_IFDIR:
1154        if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container))
1155          fprintf(stderr, "SSL_CTX_load_verify_locations failed");
1156        break;
1157      default:
1158        if (1 != SSL_CTX_load_verify_locations(ctx, NULL, ca_cert_container))
1159        {
1160          fprintf(stderr, "SSL_CTX_load_verify_locations failed");
1161          die("Unable to load CA certficate container %s", ca_cert_container);
1162        }
1163      }
1164    }
1165  }
1166
1167  if (NULL == (s_bio = BIO_new(BIO_s_connect())))
1168    die ("connect BIO setup failed");
1169  setup_proxy(s_bio);
1170  if (NULL == (ssl = SSL_new(ctx)))
1171    die ("SSL setup failed");
1172  SSL_set_bio(ssl, s_bio, s_bio);
1173
1174  if (time_is_an_illusion)
1175  {
1176    SSL_set_info_callback(ssl, openssl_time_callback);
1177  }
1178
1179  SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
1180  verb("V: opening socket to %s:%s", host, port);
1181  if ( (1 != BIO_set_conn_hostname(s_bio, host)) ||
1182       (1 != BIO_set_conn_port(s_bio, port)) )
1183    die ("Failed to initialize connection to `%s:%s'", host, port);
1184
1185  // This should run in seccomp
1186  // eg:     prctl(PR_SET_SECCOMP, 1);
1187  if (1 != SSL_connect(ssl))
1188    die ("SSL connection failed");
1189
1190  // from /usr/include/openssl/ssl3.h
1191  //  ssl->s3->server_random is an unsigned char of 32 bits
1192  memcpy(&result_time, ssl->s3->server_random, sizeof (uint32_t));
1193  verb("V: In TLS response, T=%lu", (unsigned long)ntohl(result_time));
1194
1195  if (http) {
1196    char buf[1024];
1197    verb_debug ("V: Starting HTTP");
1198    if (snprintf(buf, sizeof(buf),
1199                 HTTP_REQUEST, HTTPS_USER_AGENT, hostname_to_verify) >= 1024)
1200      die("hostname too long");
1201    buf[1023]='\0'; /* Unneeded. */
1202    verb_debug ("V: Writing HTTP request");
1203    if (1 != write_all_to_ssl(ssl, buf))
1204      die ("write all to bio failed.");
1205    verb_debug ("V: Reading HTTP response");
1206    if (1 != read_http_date_from_ssl(ssl, &result_time))
1207      die ("read all from bio failed.");
1208    verb ("V: Received HTTP response. T=%lu", (unsigned long)result_time);
1209
1210    result_time = htonl(result_time);
1211  }
1212
1213  // Verify the peer certificate against the CA certs on the local system
1214  if (ca_racket) {
1215    inspect_key (ssl, hostname_to_verify);
1216  } else {
1217    verb ("V: Certificate verification skipped!");
1218  }
1219  check_key_length(ssl);
1220
1221  memcpy(time_map, &result_time, sizeof (uint32_t));
1222
1223  SSL_free(ssl);
1224  SSL_CTX_free(ctx);
1225}
1226#endif /* USE_POLARSSL */
1227/** drop root rights and become 'nobody' */
1228
1229int
1230main(int argc, char **argv)
1231{
1232  uint32_t *time_map;
1233  struct tlsdate_time start_time, end_time, warp_time;
1234  int status;
1235  pid_t ssl_child;
1236  long long rt_time_ms;
1237  uint32_t server_time_s;
1238  int setclock;
1239  int showtime;
1240  int showtime_raw;
1241  int timewarp;
1242  int leap;
1243  int http;
1244
1245  if (argc != 13)
1246    return 1;
1247  host = argv[1];
1248  hostname_to_verify = argv[1];
1249  port = argv[2];
1250  protocol = argv[3];
1251  ca_cert_container = argv[6];
1252  ca_racket = (0 != strcmp ("unchecked", argv[4]));
1253  verbose = (0 != strcmp ("quiet", argv[5]));
1254  verbose_debug = (0 != strcmp ("verbose", argv[5]));
1255  setclock = (0 == strcmp ("setclock", argv[7]));
1256  showtime = (0 == strcmp ("showtime", argv[8]));
1257  showtime_raw = (0 == strcmp ("showtime=raw", argv[8]));
1258  timewarp = (0 == strcmp ("timewarp", argv[9]));
1259  leap = (0 == strcmp ("leapaway", argv[10]));
1260  proxy = (0 == strcmp ("none", argv[11]) ? NULL : argv[11]);
1261  http = (0 == (strcmp("http", argv[12])));
1262
1263  /* Initalize warp_time with RECENT_COMPILE_DATE */
1264  clock_init_time(&warp_time, RECENT_COMPILE_DATE, 0);
1265
1266  verb ("V: RECENT_COMPILE_DATE is %lu.%06lu",
1267       (unsigned long) CLOCK_SEC(&warp_time),
1268       (unsigned long) CLOCK_USEC(&warp_time));
1269
1270  if (1 != timewarp)
1271  {
1272    verb ("V: we'll do the time warp another time - we're not setting clock");
1273  }
1274
1275  /* We are not going to set the clock, thus no need to stay root */
1276  if (0 == setclock && 0 == timewarp)
1277  {
1278    verb ("V: attemping to drop administrator privileges");
1279    drop_privs_to (UNPRIV_USER, UNPRIV_GROUP, NULL);
1280  }
1281
1282  // We cast the mmap value to remove this error when compiling with g++:
1283  // src/tlsdate-helper.c: In function ‘int main(int, char**)’:
1284  // src/tlsdate-helper.c:822:41: error: invalid conversion from ‘void*’ to ‘uint32_t
1285  time_map = (uint32_t *) mmap (NULL, sizeof (uint32_t),
1286       PROT_READ | PROT_WRITE,
1287       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
1288   if (MAP_FAILED == time_map)
1289  {
1290    fprintf (stderr, "mmap failed: %s",
1291             strerror (errno));
1292    return 1;
1293  }
1294
1295  /* Get the current time from the system clock. */
1296  if (0 != clock_get_real_time(&start_time))
1297  {
1298    die ("Failed to read current time of day: %s", strerror (errno));
1299  }
1300
1301  verb ("V: time is currently %lu.%06lu",
1302       (unsigned long) CLOCK_SEC(&start_time),
1303       (unsigned long) CLOCK_NSEC(&start_time));
1304
1305  if (((unsigned long) CLOCK_SEC(&start_time)) < ((unsigned long) CLOCK_SEC(&warp_time)))
1306  {
1307    verb ("V: local clock time is less than RECENT_COMPILE_DATE");
1308    if (timewarp)
1309    {
1310      verb ("V: Attempting to warp local clock into the future");
1311      if (0 != clock_set_real_time(&warp_time))
1312      {
1313        die ("setting time failed: %s (Attempted to set clock to %lu.%06lu)",
1314        strerror (errno),
1315        (unsigned long) CLOCK_SEC(&warp_time),
1316        (unsigned long) CLOCK_SEC(&warp_time));
1317      }
1318      if (0 != clock_get_real_time(&start_time))
1319      {
1320        die ("Failed to read current time of day: %s", strerror (errno));
1321      }
1322      verb ("V: time is currently %lu.%06lu",
1323           (unsigned long) CLOCK_SEC(&start_time),
1324           (unsigned long) CLOCK_NSEC(&start_time));
1325      verb ("V: It's just a step to the left...");
1326    }
1327  } else {
1328    verb ("V: time is greater than RECENT_COMPILE_DATE");
1329  }
1330
1331  /* initialize to bogus value, just to be on the safe side */
1332  *time_map = 0;
1333
1334  /* Run SSL interaction in separate process (and not as 'root') */
1335  ssl_child = fork ();
1336  if (-1 == ssl_child)
1337    die ("fork failed: %s", strerror (errno));
1338  if (0 == ssl_child)
1339  {
1340    drop_privs_to (UNPRIV_USER, UNPRIV_GROUP, NULL);
1341    run_ssl (time_map, leap, http);
1342    (void) munmap (time_map, sizeof (uint32_t));
1343    _exit (0);
1344  }
1345  if (ssl_child != platform->process_wait (ssl_child, &status, 1))
1346    die ("waitpid failed: %s", strerror (errno));
1347  if (! (WIFEXITED (status) && (0 == WEXITSTATUS (status)) ))
1348    die ("child process failed in SSL handshake");
1349
1350  if (0 != clock_get_real_time(&end_time))
1351    die ("Failed to read current time of day: %s", strerror (errno));
1352
1353  /* calculate RTT */
1354  rt_time_ms = (CLOCK_SEC(&end_time) - CLOCK_SEC(&start_time)) * 1000 + (CLOCK_USEC(&end_time) - CLOCK_USEC(&start_time)) / 1000;
1355  if (rt_time_ms < 0)
1356    rt_time_ms = 0; /* non-linear time... */
1357#ifdef USE_POLARSSL
1358  server_time_s = *time_map;
1359#else
1360  server_time_s = ntohl (*time_map);
1361#endif
1362  // We should never have a time_map of zero here;
1363  // It either stayed zero or we have a false ticker.
1364  if ( 0 == server_time_s )
1365    die ("child process failed to update time map; weird platform issues?");
1366  munmap (time_map, sizeof (uint32_t));
1367
1368  verb ("V: server time %u (difference is about %d s) was fetched in %lld ms",
1369  (unsigned int) server_time_s,
1370  CLOCK_SEC(&start_time) - server_time_s,
1371  rt_time_ms);
1372
1373  /* warning if the handshake took too long */
1374  if (rt_time_ms > TLS_RTT_UNREASONABLE) {
1375    die ("the TLS handshake took more than %d msecs - consider using a different " \
1376      "server or run it again", TLS_RTT_UNREASONABLE);
1377  }
1378  if (rt_time_ms > TLS_RTT_THRESHOLD) {
1379    verb ("V: the TLS handshake took more than %d msecs - consider using a different " \
1380      "server or run it again", TLS_RTT_THRESHOLD);
1381  }
1382
1383  if (showtime_raw)
1384  {
1385    fwrite(&server_time_s, sizeof(server_time_s), 1, stdout);
1386  }
1387
1388  if (showtime)
1389  {
1390     struct tm  ltm;
1391     time_t tim = server_time_s;
1392     char       buf[256];
1393
1394     localtime_r(&tim, &ltm);
1395     if (0 == strftime(buf, sizeof buf, "%a %b %e %H:%M:%S %Z %Y", &ltm))
1396     {
1397       die ("strftime returned 0");
1398     }
1399     fprintf(stdout, "%s\n", buf);
1400  }
1401
1402  /* finally, actually set the time */
1403  if (setclock)
1404  {
1405    struct tlsdate_time server_time;
1406
1407    clock_init_time(&server_time,  server_time_s + (rt_time_ms / 2 / 1000),
1408                   (rt_time_ms / 2) % 1000);
1409
1410    // We should never receive a time that is before the time we were last
1411    // compiled; we subscribe to the linear theory of time for this program
1412    // and this program alone!
1413    if (CLOCK_SEC(&server_time) >= MAX_REASONABLE_TIME)
1414      die("remote server is a false ticker from the future!");
1415    if (CLOCK_SEC(&server_time) <= RECENT_COMPILE_DATE)
1416      die ("remote server is a false ticker!");
1417    if (0 != clock_set_real_time(&server_time))
1418      die ("setting time failed: %s (Difference from server is about %d s)",
1419     strerror (errno),
1420     CLOCK_SEC(&start_time) - server_time_s);
1421    verb ("V: setting time succeeded");
1422  }
1423  return 0;
1424}
1425