1/* 2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* ----------------------------------------------------------------------------- 25 * 26 * Theory of operation : 27 * 28 * L2TP plugin for vpnd 29 * 30----------------------------------------------------------------------------- */ 31 32 33/* ----------------------------------------------------------------------------- 34 Includes 35----------------------------------------------------------------------------- */ 36 37#include <stdio.h> 38#include <ctype.h> 39#include <stdlib.h> 40#include <string.h> 41#include <unistd.h> 42#include <signal.h> 43#include <errno.h> 44#include <fcntl.h> 45#include <syslog.h> 46#include <netdb.h> 47#include <pwd.h> 48#include <setjmp.h> 49#include <sys/param.h> 50#include <sys/types.h> 51#include <sys/wait.h> 52#include <sys/time.h> 53#include <sys/resource.h> 54#include <sys/socket.h> 55#include <sys/stat.h> 56#include <sys/socket.h> 57#include <netinet/in.h> 58#include <arpa/inet.h> 59#include <syslog.h> 60#include <sys/ioctl.h> 61#include <net/if.h> 62#include <net/route.h> 63#include <pthread.h> 64#include <sys/kern_event.h> 65#include <sys/sysctl.h> 66#include <netinet/in_var.h> 67#include <sys/un.h> 68#include <CoreFoundation/CFNumber.h> 69#include <CoreFoundation/CFBundle.h> 70#include <SystemConfiguration/SystemConfiguration.h> 71 72#define APPLE 1 73 74//#include "../L2TP-extension/l2tpk.h" 75#include "../../../Helpers/vpnd/ipsec_utils.h" 76#include "../../../Helpers/vpnd/vpnplugins.h" 77#include "../../../Helpers/vpnd/vpnd.h" 78#include "../../../Helpers/vpnd/RASSchemaDefinitions.h" 79#include "../../../Helpers/vpnd/cf_utils.h" 80#include "l2tp.h" 81 82#include "vpn_control.h" 83 84 85// ---------------------------------------------------------------------------- 86// � Private Globals 87// ---------------------------------------------------------------------------- 88#define MAXSECRETLEN 256 /* max length of secret */ 89 90static CFBundleRef bundle = 0; 91static CFBundleRef pppbundle = 0; 92static int listen_sockfd = -1; 93static int opt_noipsec = 0; 94static int key_preference = -1; 95static struct sockaddr_in listen_address; 96static struct sockaddr_in our_address; 97static struct sockaddr_in any_address; 98static int debug = 0; 99static int racoon_sockfd = -1; 100static int sick_timeleft = 0; 101static int ping_timeleft = 0; 102static int racoon_ping_seed = 0; 103#define IPSEC_SICK_TIME 60 //seconds 104#define IPSEC_PING_TIME 5 //seconds 105#define IPSEC_REPAIR_TIME 10 //seconds 106 107static CFMutableDictionaryRef ipsec_dict = NULL; 108static CFMutableDictionaryRef ipsec_settings = NULL; 109 110int l2tpvpn_get_pppd_args(struct vpn_params *params, int reload); 111int l2tpvpn_health_check(int *outfd, int event); 112int l2tpvpn_lb_redirect(struct in_addr *cluster_addr, struct in_addr *redirect_addr); 113int l2tpvpn_listen(void); 114int l2tpvpn_accept(void); 115int l2tpvpn_refuse(void); 116void l2tpvpn_close(void); 117int l2tp_set_delegated_process(int fd, int pid); 118 119static u_long load_kext(char *kext, int byBundleID); 120 121/* ----------------------------------------------------------------------------- 122plugin entry point, called by vpnd 123ref is the vpn bundle reference 124pppref is the ppp bundle reference 125bundles can be layout in two different ways 126- As simple vpn bundles (bundle.vpn). the bundle contains the vpn bundle binary. 127- As full ppp bundles (bundle.ppp). The bundle contains the ppp bundle binary, 128and also the vpn kext and the vpn bundle binary in its Plugins directory. 129if a simple vpn bundle was used, pppref will be NULL. 130if a ppp bundle was used, the vpn plugin will be able to get access to the 131Plugins directory and load the vpn kext. 132----------------------------------------------------------------------------- */ 133int start(struct vpn_channel* the_vpn_channel, CFBundleRef ref, CFBundleRef pppref, int debug_mode, int log_verbose) 134{ 135 char name[MAXPATHLEN]; 136 CFURLRef url; 137 size_t len; 138 int nb_cpu = 1, nb_threads = 0; 139 140 debug = debug_mode; 141 142 /* first load the kext if we are loaded as part of a ppp bundle */ 143 if (pppref) { 144 while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0) 145 if (errno != EINTR) 146 break; 147 if (listen_sockfd < 0) { 148 vpnlog(LOG_DEBUG, "L2TP plugin: first call to socket failed - attempting to load kext\n"); 149 if ((url = CFBundleCopyBundleURL(pppref))) { 150 name[0] = 0; 151 CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)name, MAXPATHLEN - 1); 152 CFRelease(url); 153 strlcat(name, "/", sizeof(name)); 154 if ((url = CFBundleCopyBuiltInPlugInsURL(pppref))) { 155 CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)(name + strlen(name)), 156 MAXPATHLEN - strlen(name) - strlen(L2TP_NKE) - 1); 157 CFRelease(url); 158 strlcat(name, "/", sizeof(name)); 159 strlcat(name, L2TP_NKE, sizeof(name)); 160#if !TARGET_OS_EMBEDDED // This file is not built for Embedded 161 if (!load_kext(name, 0)) 162#else 163 if (!load_kext(L2TP_NKE_ID, 1)) 164#endif 165 while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0) 166 if (errno != EINTR) 167 break; 168 } 169 } 170 if (listen_sockfd < 0) { 171 vpnlog(LOG_ERR, "L2TP plugin: Unable to load L2TP kernel extension\n"); 172 return -1; 173 } 174 } 175 } 176 177#if !TARGET_OS_EMBEDDED // This file is not built for Embedded 178 /* increase the number of threads for l2tp to nb cpus - 1 */ 179 len = sizeof(int); 180 sysctlbyname("hw.ncpu", &nb_cpu, &len, NULL, 0); 181 if (nb_cpu > 1) { 182 sysctlbyname("net.ppp.l2tp.nb_threads", &nb_threads, &len, 0, 0); 183 if (nb_threads < (nb_cpu - 1)) { 184 nb_threads = nb_cpu - 1; 185 sysctlbyname("net.ppp.l2tp.nb_threads", 0, 0, &nb_threads, sizeof(int)); 186 } 187 } 188#endif 189 190 /* retain reference */ 191 bundle = ref; 192 CFRetain(bundle); 193 194 pppbundle = pppref; 195 if (pppbundle) 196 CFRetain(pppbundle); 197 198 // hookup our socket handlers 199 bzero(the_vpn_channel, sizeof(struct vpn_channel)); 200 the_vpn_channel->get_pppd_args = l2tpvpn_get_pppd_args; 201 the_vpn_channel->listen = l2tpvpn_listen; 202 the_vpn_channel->accept = l2tpvpn_accept; 203 the_vpn_channel->refuse = l2tpvpn_refuse; 204 the_vpn_channel->close = l2tpvpn_close; 205 the_vpn_channel->health_check = l2tpvpn_health_check; 206 the_vpn_channel->lb_redirect = l2tpvpn_lb_redirect; 207 208 return 0; 209} 210 211/* ----------------------------------------------------------------------------- 212 l2tpvpn_get_pppd_args 213----------------------------------------------------------------------------- */ 214int l2tpvpn_get_pppd_args(struct vpn_params *params, int reload) 215{ 216 217 CFStringRef string; 218 int noipsec = 0; 219 CFMutableDictionaryRef dict = NULL; 220 221 if (reload) { 222 noipsec = opt_noipsec; 223 } 224 225 if (params->serverRef) { 226 /* arguments from the preferences file */ 227 addstrparam(params->exec_args, ¶ms->next_arg_index, "l2tpmode", "answer"); 228 229 string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPTransport); 230 if (string && CFEqual(string, kRASValL2TPTransportIP)) { 231 addparam(params->exec_args, ¶ms->next_arg_index, "l2tpnoipsec"); 232 opt_noipsec = 1; 233 } 234 235 dict = (CFMutableDictionaryRef)CFDictionaryGetValue(params->serverRef, kRASEntIPSec); 236 if (isDictionary(dict)) { 237 /* get the parameters from the IPSec dictionary */ 238 dict = CFDictionaryCreateMutableCopy(0, 0, dict); 239 } 240 else { 241 /* get the parameters from the L2TP dictionary */ 242 dict = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 243 244 string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPIPSecSharedSecretEncryption); 245 if (isString(string)) 246 CFDictionarySetValue(dict, kRASPropIPSecSharedSecretEncryption, string); 247 248 string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPIPSecSharedSecret); 249 if (isString(string)) 250 CFDictionarySetValue(dict, kRASPropIPSecSharedSecret, string); 251 } 252 253 } else { 254 /* arguments from command line */ 255 if (opt_noipsec) 256 addparam(params->exec_args, ¶ms->next_arg_index, "l2tpnoipsec"); 257 } 258 259 if (reload) { 260 if (noipsec != opt_noipsec || 261 !CFEqual(dict, ipsec_settings)) { 262 vpnlog(LOG_ERR, "reload prefs - IPSec shared secret cannot be changed\n"); 263 if (dict) 264 CFRelease(dict); 265 return -1; 266 } 267 } 268 269 if (ipsec_settings) 270 CFRelease(ipsec_settings); 271 ipsec_settings = dict; 272 273 return 0; 274} 275 276/* ----------------------------------------------------------------------------- 277 l2tpvpn_health_check 278----------------------------------------------------------------------------- */ 279int l2tpvpn_health_check(int *outfd, int event) 280{ 281 282 size_t size; 283 struct sockaddr_un sun; 284 int ret = -1, flags; 285 286 char data[256]; 287 struct vpnctl_hdr *hdr = (struct vpnctl_hdr *)data; 288 289 switch (event) { 290 291 case 0: // periodic check 292 293 // no ipsec, no need for health check 294 if (opt_noipsec) { 295 *outfd = -1; 296 break; 297 } 298 299 if (sick_timeleft) { 300 sick_timeleft--; 301 if (sick_timeleft == 0) 302 goto fail; 303 } 304 305 // racoon socket is already opened, just query racoon 306 if (racoon_sockfd != -1) { 307 308 if (ping_timeleft) { 309 ping_timeleft--; 310 if (ping_timeleft == 0) { 311 // error on racoon socket. racoon exited ? 312 ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover 313 sick_timeleft = IPSEC_SICK_TIME; 314 goto fail; 315 } 316 } 317 else { 318 // query racoon here 319 bzero(hdr, sizeof(struct vpnctl_hdr)); 320 hdr->msg_type = htons(VPNCTL_CMD_PING); 321 hdr->cookie = htonl(++racoon_ping_seed); 322 ping_timeleft = IPSEC_PING_TIME; // give few seconds to get a reply 323 writen(racoon_sockfd, hdr, sizeof(struct vpnctl_hdr)); 324 } 325 break; 326 } 327 328 // attempt to kill and restart racoon every 10 seconds 329 if ((sick_timeleft % IPSEC_REPAIR_TIME) == 0) { 330 vpnlog(LOG_ERR, "IPSecSelfRepair\n"); 331 IPSecSelfRepair(); 332 } 333 334 // racoon socket is not yet opened, so opened it 335 /* open the racoon control socket */ 336 racoon_sockfd = socket(PF_LOCAL, SOCK_STREAM, 0); 337 if (racoon_sockfd < 0) { 338 vpnlog(LOG_ERR, "Unable to create racoon control socket (errno = %d)\n", errno); 339 goto fail; 340 } 341 342 bzero(&sun, sizeof(sun)); 343 sun.sun_family = AF_LOCAL; 344 strncpy(sun.sun_path, "/var/run/vpncontrol.sock", sizeof(sun.sun_path)); 345 346 if (connect(racoon_sockfd, (struct sockaddr *)&sun, sizeof(sun)) < 0) { 347 vpnlog(LOG_ERR, "Unable to connect racoon control socket (errno = %d)\n", errno); 348 ret = -2; 349 goto fail; 350 } 351 352 if ((flags = fcntl(racoon_sockfd, F_GETFL)) == -1 353 || fcntl(racoon_sockfd, F_SETFL, flags | O_NONBLOCK) == -1) { 354 vpnlog(LOG_ERR, "Unable to set racoon control socket in non-blocking mode (errno = %d)\n", errno); 355 ret = -2; 356 goto fail; 357 } 358 359 *outfd = racoon_sockfd; 360 sick_timeleft = 0; 361 ping_timeleft = 0; 362 break; 363 364 case 1: // event on racoon fd 365 size = recvfrom (racoon_sockfd, data, sizeof(struct vpnctl_hdr), 0, 0, 0); 366 if (size == 0) { 367 // error on racoon socket. racoon exited ? 368 ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover 369 sick_timeleft = IPSEC_SICK_TIME; 370 ping_timeleft = 0; 371 goto fail; 372 } 373 374 /* read end of packet */ 375 if (ntohs(hdr->len)) { 376 size = recvfrom (racoon_sockfd, data + sizeof(struct vpnctl_hdr), ntohs(hdr->len), 0, 0, 0); 377 if (size == 0) { 378 // error on racoon socket. racoon exited ? 379 ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover 380 sick_timeleft = IPSEC_SICK_TIME; 381 ping_timeleft = 0; 382 goto fail; 383 } 384 } 385 386 switch (ntohs(hdr->msg_type)) { 387 388 case VPNCTL_CMD_PING: 389 390 if (racoon_ping_seed == ntohl(hdr->cookie)) { 391 // good ! 392 ping_timeleft = 0; 393 //vpnlog(LOG_DEBUG, "receive racoon PING REPLY cookie %d\n", ntohl(hdr->cookie)); 394 } 395 break; 396 397 default: 398 /* ignore other messages */ 399 //vpnlog(LOG_DEBUG, "receive racoon message type %d, result %d\n", ntohs(hdr->msg_type), ntohs(hdr->result)); 400 break; 401 402 } 403 break; 404 405 } 406 407 return 0; 408 409fail: 410 if (racoon_sockfd != -1) { 411 close(racoon_sockfd); 412 racoon_sockfd = -1; 413 *outfd = -1; 414 } 415 return ret; 416} 417 418// ---------------------------------------------------------------------------- 419// notify racoon of the new redirection 420// ---------------------------------------------------------------------------- 421int l2tpvpn_lb_redirect(struct in_addr *cluster_addr, struct in_addr *redirect_addr) 422{ 423 424 if (racoon_sockfd == -1) { 425 return -1; 426 } 427 428 struct vpnctl_cmd_redirect msg; 429 bzero(&msg, sizeof(msg)); 430 msg.hdr.len = htons(sizeof(msg) - sizeof(msg.hdr)); 431 msg.hdr.msg_type = htons(VPNCTL_CMD_REDIRECT); 432 msg.address = cluster_addr->s_addr; 433 msg.redirect_address = redirect_addr->s_addr; 434 msg.force = htons(1); 435 writen(racoon_sockfd, &msg, sizeof(msg)); 436 return 0; 437} 438 439/* ----------------------------------------------------------------------------- 440 system call wrappers 441----------------------------------------------------------------------------- */ 442int l2tp_sys_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) 443{ 444 while (getsockopt(sockfd, level, optname, optval, optlen) < 0) 445 if (errno != EINTR) { 446 vpnlog(LOG_ERR, "L2TP plugin: error calling getsockopt for option %d (%s)\n", optname, strerror(errno)); 447 return -1; 448 } 449 return 0; 450} 451 452int l2tp_sys_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen) 453{ 454 while (setsockopt(sockfd, level, optname, optval, optlen) < 0) 455 if (errno != EINTR) { 456 vpnlog(LOG_ERR, "L2TP plugin: error calling setsockopt for option %d (%s)\n", optname, strerror(errno)); 457 return -1; 458 } 459 return 0; 460} 461 462int l2tp_sys_recvfrom(int sockfd, void *buff, size_t nbytes, int flags, 463 struct sockaddr *from, socklen_t *addrlen) 464{ 465 while (recvfrom(sockfd, buff, nbytes, flags, from, addrlen) < 0) 466 if (errno != EINTR) { 467 vpnlog(LOG_ERR, "L2TP plugin: error calling recvfrom = %s\n", strerror(errno)); 468 return -1; 469 } 470 return 0; 471} 472 473/* ----------------------------------------------------------------------------- 474 set_flag 475----------------------------------------------------------------------------- */ 476int set_flag(int fd, int set, u_int32_t flag) 477{ 478 socklen_t optlen; 479 u_int32_t flags; 480 481 optlen = 4; 482 if (l2tp_sys_getsockopt(fd, PPPPROTO_L2TP, L2TP_OPT_FLAGS, &flags, &optlen) < 0) 483 return -1; 484 485 flags = set ? (flags | flag) : (flags & ~flag); 486 if (l2tp_sys_setsockopt(fd, PPPPROTO_L2TP, L2TP_OPT_FLAGS, &flags, 4) < 0) 487 return -1; 488 489 return 0; 490} 491 492/* ----------------------------------------------------------------------------- 493 closeall 494----------------------------------------------------------------------------- */ 495static void closeall() 496{ 497 int i; 498 499 for (i = getdtablesize() - 1; i >= 0; i--) close(i); 500 open("/dev/null", O_RDWR, 0); 501 dup(0); 502 dup(0); 503 return; 504} 505 506 507/* ----------------------------------------------------------------------------- 508 load_kext 509----------------------------------------------------------------------------- */ 510u_long load_kext(char *kext, int byBundleID) 511{ 512 int pid; 513 514 if ((pid = fork()) < 0) 515 return 1; 516 517 if (pid == 0) { 518 closeall(); 519 // PPP kernel extension not loaded, try load it... 520 if (byBundleID) 521 execle("/sbin/kextload", "kextload", "-b", kext, (char *)0, (char *)0); 522 else 523 execle("/sbin/kextload", "kextload", kext, (char *)0, (char *)0); 524 exit(1); 525 } 526 527 while (waitpid(pid, 0, 0) < 0) { 528 if (errno == EINTR) 529 continue; 530 return 1; 531 } 532 return 0; 533} 534 535/* ----------------------------------------------------------------------------- 536 ----------------------------------------------------------------------------- */ 537int l2tp_set_delegated_process(int fd, int pid) 538{ 539 setsockopt(fd, PPPPROTO_L2TP, L2TP_OPT_SETDELEGATEDPID, &pid, sizeof(pid)); 540 return 0; 541} 542 543/* ----------------------------------------------------------------------------- 544----------------------------------------------------------------------------- */ 545int l2tp_set_ouraddress(int fd, struct sockaddr *addr) 546{ 547 socklen_t optlen; 548 549 setsockopt(fd, PPPPROTO_L2TP, L2TP_OPT_OURADDRESS, addr, sizeof(*addr)); 550 /* get the address to retrieve the actual port used */ 551 optlen = sizeof(*addr); 552 getsockopt(fd, PPPPROTO_L2TP, L2TP_OPT_OURADDRESS, addr, &optlen); 553 return 0; 554} 555 556/* ----------------------------------------------------------------------------- 557 l2tpvpn_listen - called by vpnd to setup listening socket 558----------------------------------------------------------------------------- */ 559int l2tpvpn_listen(void) 560{ 561 char *errstr; 562 563 if (listen_sockfd <= 0) 564 return -1; 565 566 //set_flag(listen_sockfd, kerneldebug & 1, L2TP_FLAG_DEBUG); 567 set_flag(listen_sockfd, 1, L2TP_FLAG_CONTROL); 568 set_flag(listen_sockfd, !opt_noipsec, L2TP_FLAG_IPSEC); 569 l2tp_set_delegated_process(listen_sockfd, getpid()); // must be set before calling l2tp_set_ouraddress 570 571 /* unknown src and dst addresses */ 572 any_address.sin_len = sizeof(any_address); 573 any_address.sin_family = AF_INET; 574 any_address.sin_port = 0; 575 any_address.sin_addr.s_addr = INADDR_ANY; 576 577 /* bind the socket in the kernel with L2TP port */ 578 listen_address.sin_len = sizeof(listen_address); 579 listen_address.sin_family = AF_INET; 580 listen_address.sin_port = htons(L2TP_UDP_PORT); 581 listen_address.sin_addr.s_addr = INADDR_ANY; 582 l2tp_set_ouraddress(listen_sockfd, (struct sockaddr *)&listen_address); 583 our_address = listen_address; 584 585 /* add security policies */ 586 if (!opt_noipsec) { 587 588 CFStringRef auth_method; 589 CFStringRef string; 590 CFDataRef data; 591 uint32_t natt_multiple_users; 592 593 /* get authentication method from the IPSec dict */ 594 auth_method = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecAuthenticationMethod); 595 if (!isString(auth_method)) 596 auth_method = kRASValIPSecAuthenticationMethodSharedSecret; 597 598 /* get setting for nat traversal multiple user support - default is enabled for server */ 599 GetIntFromDict(ipsec_settings, kRASPropIPSecNattMultipleUsersEnabled, &natt_multiple_users, 1); 600 601 ipsec_dict = IPSecCreateL2TPDefaultConfiguration( 602 &our_address, &any_address, NULL, 603 auth_method, 0, natt_multiple_users, 0); 604 605 /* set the authentication information */ 606 if (CFEqual(auth_method, kRASValIPSecAuthenticationMethodSharedSecret)) { 607 string = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecSharedSecret); 608 if (isString(string)) 609 CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecret, string); 610 else if (isData(string) && ((CFDataGetLength((CFDataRef)string) % sizeof(UniChar)) == 0)) { 611 CFStringEncoding encoding; 612 613 data = (CFDataRef)string; 614#if __BIG_ENDIAN__ 615 encoding = (*(CFDataGetBytePtr(data) + 1) == 0x00) ? kCFStringEncodingUTF16LE : kCFStringEncodingUTF16BE; 616#else // __LITTLE_ENDIAN__ 617 encoding = (*(CFDataGetBytePtr(data) ) == 0x00) ? kCFStringEncodingUTF16BE : kCFStringEncodingUTF16LE; 618#endif 619 string = CFStringCreateWithBytes(NULL, (const UInt8 *)CFDataGetBytePtr(data), CFDataGetLength(data), encoding, FALSE); 620 CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecret, string); 621 CFRelease(string); 622 } 623 string = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecSharedSecretEncryption); 624 if (isString(string)) 625 CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecretEncryption, string); 626 } 627 else if (CFEqual(auth_method, kRASValIPSecAuthenticationMethodCertificate)) { 628 data = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecLocalCertificate); 629 if (isData(data)) 630 CFDictionarySetValue(ipsec_dict, kRASPropIPSecLocalCertificate, data); 631 } 632 633 if (IPSecApplyConfiguration(ipsec_dict, &errstr) 634 || IPSecInstallPolicies(ipsec_dict, -1, &errstr)) { 635 vpnlog(LOG_ERR, "L2TP plugin: cannot configure secure transport (%s).\n", errstr); 636 IPSecRemoveConfiguration(ipsec_dict, &errstr); 637 CFRelease(ipsec_dict); 638 ipsec_dict = 0; 639 return -1; 640 } 641 642 /* set IPSec Key management to prefer most recent key */ 643 if (IPSecSetSecurityAssociationsPreference(&key_preference, 0)) 644 vpnlog(LOG_ERR, "L2TP plugin: cannot set IPSec Key management preference (error %d)\n", errno); 645 646 sick_timeleft = IPSEC_SICK_TIME; 647 ping_timeleft = 0; 648 649 } 650 651 return listen_sockfd; 652} 653 654 655/* ----------------------------------------------------------------------------- 656 l2tpvpn_accept 657----------------------------------------------------------------------------- */ 658int l2tpvpn_accept(void) 659{ 660 661 u_int8_t recv_buf[1500]; 662 socklen_t addrlen; 663 struct sockaddr_in6 from; 664 int newSockfd; 665 666 /* we should check if there are too many call from the same IP address 667 in the last xxx minutes, proving a denial of service attack */ 668 669 while((newSockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0) 670 if (errno != EINTR) { 671 vpnlog(LOG_ERR, "L2TP plugin: Unable to open L2TP socket during accept\n"); 672 return -1; 673 } 674 675 /* accept the call. it will copy the data to the new socket */ 676 //set_flag(newSockfd, kerneldebug & 1, L2TP_FLAG_DEBUG); 677 setsockopt(newSockfd, PPPPROTO_L2TP, L2TP_OPT_ACCEPT, 0, 0); 678 679 /* read the duplicated SCCRQ from the listen socket and ignore for now */ 680 if (l2tp_sys_recvfrom(listen_sockfd, recv_buf, 1500, MSG_DONTWAIT, (struct sockaddr*)&from, &addrlen) < 0) 681 return -1; 682 683 return newSockfd; 684} 685 686 687/* ----------------------------------------------------------------------------- 688 l2tpvpn_refuse - called by vpnd to refuse an incomming connection. 689 return values: -1 error 690 socket# launch pppd with next server address 691 0 handled, do nothing 692 693----------------------------------------------------------------------------- */ 694int l2tpvpn_refuse(void) 695{ 696 u_int8_t recv_buf[1500]; 697 socklen_t addrlen; 698 struct sockaddr_in6 from; 699 int newSockfd; 700 701 /* we should check if there are too many call from the same IP address 702 in the last xxx minutes, proving a denial of service attack */ 703 704 /* need t read the packet to empty the socket buffer */ 705 while((newSockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0) 706 if (errno != EINTR) { 707 vpnlog(LOG_ERR, "L2TP plugin: Unable to open L2TP socket during refuse\n"); 708 return -1; 709 } 710 711 /* accept the call. it will copy the data to the new socket */ 712 setsockopt(newSockfd, PPPPROTO_L2TP, L2TP_OPT_ACCEPT, 0, 0); 713 /* and close it right away */ 714 close(newSockfd); 715 716 /* read the duplicated SCCRQ from the listen socket and ignore for now */ 717 if (l2tp_sys_recvfrom(listen_sockfd, recv_buf, 1500, MSG_DONTWAIT, (struct sockaddr*)&from, &addrlen) < 0) 718 return -1; 719 720 return 0; 721} 722 723/* ----------------------------------------------------------------------------- 724 l2tpvpn_close 725----------------------------------------------------------------------------- */ 726void l2tpvpn_close(void) 727{ 728 729 char *errstr; 730 731 if (racoon_sockfd != -1) { 732 close(racoon_sockfd); 733 racoon_sockfd = -1; 734 } 735 736 if (listen_sockfd != -1) { 737 while (close(listen_sockfd) < 0) 738 if (errno == EINTR) 739 continue; 740 listen_sockfd = -1; 741 } 742 743 /* remove security policies */ 744 if (ipsec_dict) { 745 IPSecRemoveConfiguration(ipsec_dict, &errstr); 746 IPSecRemovePolicies(ipsec_dict, -1, &errstr); 747 /* restore IPSec Key management preference */ 748 if (IPSecSetSecurityAssociationsPreference(0, key_preference)) 749 vpnlog(LOG_ERR, "L2TP plugin: cannot reset IPSec Key management preference (error %d)\n", errno); 750 CFRelease(ipsec_dict); 751 ipsec_dict = NULL; 752 } 753 754 if (ipsec_settings) { 755 CFRelease(ipsec_settings); 756 ipsec_settings = NULL; 757 } 758 759} 760 761 762 763