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