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)27build_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)72tlsdate (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