1 /*
2  * tlsdate-monitor.c - tlsdated monitor for tlsdate.
3  * Copyright (c) 2013 The Chromium Authors. All rights reserved.
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "config.h"
9 
10 #include <assert.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <signal.h>
17 #include <sys/time.h>
18 #include <sys/wait.h>
19 #include <time.h>
20 #include <unistd.h>
21 
22 #include "src/util.h"
23 #include "src/tlsdate.h"
24 
25 static
26 char **
build_argv(struct opts * opts)27 build_argv (struct opts *opts)
28 {
29   int argc;
30   char **new_argv;
31   assert (opts->sources);
32   /* choose the next source in the list; if we're at the end, start over. */
33   if (!opts->cur_source || !opts->cur_source->next)
34     opts->cur_source = opts->sources;
35   else
36     opts->cur_source = opts->cur_source->next;
37   for (argc = 0; opts->base_argv[argc]; argc++)
38     ;
39   /* Put an arbitrary limit on the number of args. */
40   if (argc > 1024)
41     return NULL;
42   argc++; /* uncounted null terminator */
43   argc += 9;  /* -H host -p port -x proxy -Vraw -n -l */
44   new_argv = malloc (argc * sizeof (char *));
45   if (!new_argv)
46     return NULL;
47   for (argc = 0; opts->base_argv[argc]; argc++)
48     new_argv[argc] = opts->base_argv[argc];
49   new_argv[argc++] = "-H";
50   new_argv[argc++] = opts->cur_source->host;
51   new_argv[argc++] = "-p";
52   new_argv[argc++] = opts->cur_source->port;
53   if (opts->cur_source->proxy || opts->proxy)
54     {
55       char *proxy = opts->proxy ? opts->proxy : opts->cur_source->proxy;
56       if (strcmp (proxy, ""))
57         {
58           new_argv[argc++] = (char *) "-x";
59           new_argv[argc++] = proxy;
60         }
61     }
62   new_argv[argc++] = "-Vraw";
63   new_argv[argc++] = "-n";
64   if (opts->leap)
65     new_argv[argc++] = "-l";
66   new_argv[argc++] = NULL;
67   return new_argv;
68 }
69 
70 /* Run tlsdate and redirects stdout to the monitor_fd */
71 int
tlsdate(struct state * state)72 tlsdate (struct state *state)
73 {
74   char **new_argv;
75   pid_t pid;
76   switch ((pid = fork()))
77     {
78     case 0: /* child! */
79       break;
80     case -1:
81       perror ("fork() failed!");
82       return -1;
83     default:
84       verb_debug ("[tlsdate-monitor] spawned tlsdate: %d", pid);
85       state->tlsdate_pid = pid;
86       return 0;
87    }
88   if (!(new_argv = build_argv (&state->opts)))
89     fatal ("out of memory building argv");
90   /* Replace stdout with the pipe back to tlsdated */
91   if (dup2 (state->tlsdate_monitor_fd, STDOUT_FILENO) < 0)
92     {
93       perror ("dup2 failed");
94       _exit (2);
95     }
96   execve (new_argv[0], new_argv, state->envp);
97   perror ("[tlsdate-monitor] execve() failed");
98   _exit (1);
99 }
100