1 /* 2 * Copyright (C) 2009 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 <string.h> 20 #include <stdarg.h> 21 #include <signal.h> 22 #include <unistd.h> 23 #include <sys/types.h> 24 #include <sys/socket.h> 25 #include <sys/select.h> 26 27 #ifdef ANDROID_CHANGES 28 #include <sys/ioctl.h> 29 #include <linux/if.h> 30 #include <android/log.h> 31 #include <cutils/sockets.h> 32 #include <private/android_filesystem_config.h> 33 #include "keystore_get.h" 34 #endif 35 36 #include "config.h" 37 #include "libpfkey.h" 38 #include "gcmalloc.h" 39 #include "vmbuf.h" 40 #include "crypto_openssl.h" 41 #include "oakley.h" 42 #include "pfkey.h" 43 #include "schedule.h" 44 #include "isakmp_var.h" 45 #include "nattraversal.h" 46 #include "localconf.h" 47 #include "sockmisc.h" 48 #include "grabmyaddr.h" 49 #include "plog.h" 50 #include "admin.h" 51 #include "privsep.h" 52 #include "misc.h" 53 54 #ifdef ANDROID_CHANGES 55 56 static int get_control_and_arguments(int *argc, char ***argv) 57 { 58 static char *args[256]; 59 int control; 60 int i; 61 62 if ((i = android_get_control_socket("racoon")) == -1) { 63 return -1; 64 } 65 do_plog(LLV_DEBUG, "Waiting for control socket"); 66 if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) { 67 do_plog(LLV_ERROR, "Cannot get control socket"); 68 exit(-1); 69 } 70 close(i); 71 72 args[0] = (*argv)[0]; 73 for (i = 1; i < 256; ++i) { 74 unsigned char length; 75 if (recv(control, &length, 1, 0) != 1) { 76 do_plog(LLV_ERROR, "Cannot get argument length"); 77 exit(-1); 78 } 79 if (length == 0xFF) { 80 break; 81 } else { 82 int offset = 0; 83 args[i] = malloc(length + 1); 84 while (offset < length) { 85 int n = recv(control, &args[i][offset], length - offset, 0); 86 if (n > 0) { 87 offset += n; 88 } else { 89 do_plog(LLV_ERROR, "Cannot get argument value"); 90 exit(-1); 91 } 92 } 93 args[i][length] = 0; 94 } 95 } 96 do_plog(LLV_DEBUG, "Received %d arguments", i - 1); 97 98 *argc = i; 99 *argv = args; 100 return control; 101 } 102 103 static void bind_interface() 104 { 105 struct ifreq ifreqs[64]; 106 struct ifconf ifconf = {.ifc_len = sizeof(ifreqs), .ifc_req = ifreqs}; 107 struct myaddrs *p = lcconf->myaddrs; 108 109 if (ioctl(p->sock, SIOCGIFCONF, &ifconf) == -1) { 110 do_plog(LLV_WARNING, "Cannot list interfaces"); 111 return; 112 } 113 114 while (p) { 115 int i = ifconf.ifc_len / sizeof(struct ifreq) - 1; 116 while (i >= 0 && cmpsaddrwop(p->addr, &ifreqs[i].ifr_addr)) { 117 --i; 118 } 119 if (i < 0 || setsockopt(p->sock, SOL_SOCKET, SO_BINDTODEVICE, 120 ifreqs[i].ifr_name, IFNAMSIZ) == -1) { 121 do_plog(LLV_WARNING, "Cannot bind socket %d to proper interface", 122 p->sock); 123 } 124 p = p->next; 125 } 126 } 127 128 #endif 129 130 extern void setup(int argc, char **argv); 131 int f_local = 0; 132 133 static void terminate(int signal) 134 { 135 exit(1); 136 } 137 138 static void terminated() 139 { 140 do_plog(LLV_INFO, "Bye\n"); 141 } 142 143 int main(int argc, char **argv) 144 { 145 fd_set fdset; 146 int fdset_size; 147 struct myaddrs *p; 148 #ifdef ANDROID_CHANGES 149 int control = get_control_and_arguments(&argc, &argv); 150 unsigned char code = argc - 1; 151 #endif 152 153 signal(SIGHUP, terminate); 154 signal(SIGINT, terminate); 155 signal(SIGTERM, terminate); 156 signal(SIGPIPE, SIG_IGN); 157 setup(argc, argv); 158 159 do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n"); 160 atexit(terminated); 161 162 eay_init(); 163 oakley_dhinit(); 164 compute_vendorids(); 165 sched_init(); 166 167 if (pfkey_init() < 0 || isakmp_init() < 0) { 168 exit(1); 169 } 170 171 #ifdef ENABLE_NATT 172 natt_keepalive_init(); 173 #endif 174 175 #ifdef ANDROID_CHANGES 176 bind_interface(); 177 send(control, &code, 1, 0); 178 setuid(AID_VPN); 179 #endif 180 181 FD_ZERO(&fdset); 182 FD_SET(lcconf->sock_pfkey, &fdset); 183 fdset_size = lcconf->sock_pfkey; 184 for (p = lcconf->myaddrs; p; p = p->next) { 185 FD_SET(p->sock, &fdset); 186 if (fdset_size < p->sock) { 187 fdset_size = p->sock; 188 } 189 } 190 ++fdset_size; 191 192 while (1) { 193 fd_set readset = fdset; 194 struct timeval *timeout = schedular(); 195 if (select(fdset_size, &readset, NULL, NULL, timeout) < 0) { 196 exit(1); 197 } 198 if (FD_ISSET(lcconf->sock_pfkey, &readset)) { 199 pfkey_handler(); 200 } 201 for (p = lcconf->myaddrs; p; p = p->next) { 202 if (FD_ISSET(p->sock, &readset)) { 203 isakmp_handler(p->sock); 204 } 205 } 206 } 207 return 0; 208 } 209 210 /* plog.h */ 211 212 void do_plog(int level, char *format, ...) 213 { 214 if (level >= 0 && level <= 5) { 215 #ifdef ANDROID_CHANGES 216 static int levels[6] = { 217 ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, 218 ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE 219 }; 220 va_list ap; 221 va_start(ap, format); 222 __android_log_vprint(levels[level], "racoon", format, ap); 223 va_end(ap); 224 #else 225 static char *levels = "EWNIDV"; 226 fprintf(stderr, "%c: ", levels[level]); 227 va_list ap; 228 va_start(ap, format); 229 vfprintf(stderr, format, ap); 230 va_end(ap); 231 #endif 232 } 233 } 234 235 char *binsanitize(char *data, size_t length) 236 { 237 char *output = racoon_malloc(length + 1); 238 if (output) { 239 size_t i; 240 for (i = 0; i < length; ++i) { 241 output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i]; 242 } 243 output[length] = '\0'; 244 } 245 return output; 246 } 247 248 /* privsep.h */ 249 250 int privsep_pfkey_open() 251 { 252 return pfkey_open(); 253 } 254 255 void privsep_pfkey_close(int key) 256 { 257 pfkey_close(key); 258 } 259 260 vchar_t *privsep_eay_get_pkcs1privkey(char *file) 261 { 262 return eay_get_pkcs1privkey(file); 263 } 264 265 vchar_t *privsep_getpsk(const char *key, int size) 266 { 267 vchar_t *p = NULL; 268 #ifdef ANDROID_CHANGES 269 char value[KEYSTORE_MESSAGE_SIZE]; 270 int length = keystore_get(key, size, value); 271 if (length != -1 && (p = vmalloc(length)) != NULL) { 272 memcpy(p->v, value, length); 273 } 274 #else 275 if (key && (p = vmalloc(size)) != NULL) { 276 memcpy(p->v, key, p->l); 277 } 278 #endif 279 return p; 280 } 281 282 int privsep_script_exec(char *script, int name, char * const *environ) 283 { 284 return 0; 285 } 286 287 /* grabmyaddr.h */ 288 289 int getsockmyaddr(struct sockaddr *addr) 290 { 291 struct myaddrs *p; 292 for (p = lcconf->myaddrs; p; p = p->next) { 293 if (cmpsaddrstrict(addr, p->addr) == 0) { 294 return p->sock; 295 } 296 } 297 return -1; 298 } 299 300 /* misc.h */ 301 302 int racoon_hexdump(void *data, size_t length) 303 { 304 return 0; 305 } 306