1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <stdarg.h> 20 #include <signal.h> 21 #include <poll.h> 22 #include <unistd.h> 23 24 #include "config.h" 25 #include "gcmalloc.h" 26 #include "schedule.h" 27 #include "plog.h" 28 29 #ifdef ANDROID_CHANGES 30 31 #include <openssl/engine.h> 32 33 #include <string.h> 34 #include <sys/types.h> 35 #include <sys/socket.h> 36 #include <sys/ioctl.h> 37 #include <sys/stat.h> 38 #include <fcntl.h> 39 #include <errno.h> 40 #include <linux/if.h> 41 #include <linux/if_tun.h> 42 43 #include <android/log.h> 44 #include <cutils/sockets.h> 45 #include <private/android_filesystem_config.h> 46 47 static void notify_death() 48 { 49 creat("/data/misc/vpn/abort", 0); 50 } 51 52 static int android_get_control_and_arguments(int *argc, char ***argv) 53 { 54 static char *args[32]; 55 int control; 56 int i; 57 58 atexit(notify_death); 59 60 if ((i = android_get_control_socket("racoon")) == -1) { 61 return -1; 62 } 63 do_plog(LLV_DEBUG, "Waiting for control socket"); 64 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 65 do_plog(LLV_ERROR, "Cannot get control socket"); 66 exit(1); 67 } 68 close(i); 69 fcntl(control, F_SETFD, FD_CLOEXEC); 70 71 args[0] = (*argv)[0]; 72 for (i = 1; i < 32; ++i) { 73 unsigned char bytes[2]; 74 if (recv(control, &bytes[0], 1, 0) != 1 || 75 recv(control, &bytes[1], 1, 0) != 1) { 76 do_plog(LLV_ERROR, "Cannot get argument length"); 77 exit(1); 78 } else { 79 int length = bytes[0] << 8 | bytes[1]; 80 int offset = 0; 81 82 if (length == 0xFFFF) { 83 break; 84 } 85 args[i] = malloc(length + 1); 86 while (offset < length) { 87 int n = recv(control, &args[i][offset], length - offset, 0); 88 if (n > 0) { 89 offset += n; 90 } else { 91 do_plog(LLV_ERROR, "Cannot get argument value"); 92 exit(1); 93 } 94 } 95 args[i][length] = 0; 96 } 97 } 98 do_plog(LLV_DEBUG, "Received %d arguments", i - 1); 99 100 *argc = i; 101 *argv = args; 102 return control; 103 } 104 105 const char *android_hook(char **envp) 106 { 107 struct ifreq ifr = {.ifr_flags = IFF_TUN}; 108 int tun = open("/dev/tun", 0); 109 110 /* Android does not support INTERNAL_WINS4_LIST, so we just use it. */ 111 while (*envp && strncmp(*envp, "INTERNAL_WINS4_LIST=", 20)) { 112 ++envp; 113 } 114 if (!*envp) { 115 do_plog(LLV_ERROR, "Cannot find environment variable\n"); 116 exit(1); 117 } 118 if (ioctl(tun, TUNSETIFF, &ifr)) { 119 do_plog(LLV_ERROR, "Cannot allocate TUN: %s\n", strerror(errno)); 120 exit(1); 121 } 122 sprintf(*envp, "INTERFACE=%s", ifr.ifr_name); 123 return "/etc/ppp/ip-up-vpn"; 124 } 125 126 #endif 127 128 extern void setup(int argc, char **argv); 129 130 static int monitors; 131 static void (*callbacks[10])(int fd); 132 static struct pollfd pollfds[10]; 133 134 char *pname; 135 136 static void terminate(int signal) 137 { 138 exit(1); 139 } 140 141 static void terminated() 142 { 143 do_plog(LLV_INFO, "Bye\n"); 144 } 145 146 void monitor_fd(int fd, void (*callback)(int)) 147 { 148 if (fd < 0 || monitors == 10) { 149 do_plog(LLV_ERROR, "Cannot monitor fd"); 150 exit(1); 151 } 152 callbacks[monitors] = callback; 153 pollfds[monitors].fd = fd; 154 pollfds[monitors].events = callback ? POLLIN : 0; 155 ++monitors; 156 } 157 158 int main(int argc, char **argv) 159 { 160 #ifdef ANDROID_CHANGES 161 int control = android_get_control_and_arguments(&argc, &argv); 162 #if !defined(OPENSSL_IS_BORINGSSL) 163 ENGINE *engine; 164 #endif 165 166 if (control != -1) { 167 pname = "%p"; 168 monitor_fd(control, NULL); 169 170 #if !defined(OPENSSL_IS_BORINGSSL) 171 ENGINE_load_dynamic(); 172 engine = ENGINE_by_id("keystore"); 173 if (!engine || !ENGINE_init(engine)) { 174 do_plog(LLV_ERROR, "ipsec-tools: cannot load keystore engine"); 175 exit(1); 176 } 177 #endif 178 } 179 #endif 180 181 do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n"); 182 183 signal(SIGHUP, terminate); 184 signal(SIGINT, terminate); 185 signal(SIGTERM, terminate); 186 signal(SIGPIPE, SIG_IGN); 187 atexit(terminated); 188 189 setup(argc, argv); 190 191 #ifdef ANDROID_CHANGES 192 shutdown(control, SHUT_WR); 193 setuid(AID_VPN); 194 #endif 195 196 while (1) { 197 struct timeval *tv = schedular(); 198 int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1; 199 200 if (poll(pollfds, monitors, timeout) > 0) { 201 int i; 202 for (i = 0; i < monitors; ++i) { 203 if (pollfds[i].revents & POLLHUP) { 204 do_plog(LLV_INFO, "Connection is closed\n", pollfds[i].fd); 205 /* Wait for few seconds to consume late messages. */ 206 sleep(5); 207 exit(1); 208 } 209 if (pollfds[i].revents & POLLIN) { 210 callbacks[i](pollfds[i].fd); 211 } 212 } 213 } 214 } 215 216 #if !defined(OPENSSL_IS_BORINGSSL) 217 if (engine) { 218 ENGINE_finish(engine); 219 ENGINE_free(engine); 220 } 221 #endif 222 return 0; 223 } 224 225 /* plog.h */ 226 227 void do_plog(int level, char *format, ...) 228 { 229 if (level >= 0 && level <= 5) { 230 #ifdef ANDROID_CHANGES 231 static int levels[6] = { 232 ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, 233 ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE 234 }; 235 va_list ap; 236 va_start(ap, format); 237 __android_log_vprint(levels[level], "racoon", format, ap); 238 va_end(ap); 239 #else 240 static char *levels = "EWNIDV"; 241 fprintf(stderr, "%c: ", levels[level]); 242 va_list ap; 243 va_start(ap, format); 244 vfprintf(stderr, format, ap); 245 va_end(ap); 246 #endif 247 } 248 } 249 250 char *binsanitize(char *data, size_t length) 251 { 252 char *output = racoon_malloc(length + 1); 253 if (output) { 254 size_t i; 255 for (i = 0; i < length; ++i) { 256 output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i]; 257 } 258 output[length] = '\0'; 259 } 260 return output; 261 } 262