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