/* ----------------------------------------------------------------------------- l2tpvpn_listen - called by vpnd to setup listening socket ----------------------------------------------------------------------------- */ int l2tpvpn_listen(void) { if (listen_sockfd <= 0) return -1; if (!opt_noipsec) { vpnlog(LOG_INFO, "VPND L2TP plugin: start racoon...\n"); /* start racoon */ if (start_racoon(0 /*pppbundle*/, 0 /*"racoon.l2tp"*/) < 0) { vpnlog(LOG_ERR, "VPND L2TP plugin: cannot start racoon...\n"); return -1; } /* XXX if we started racoon, we will need to stop it */ /* racoon should probably provide a control API */ need_stop_racoon = 1; } set_flag(listen_sockfd, debug, L2TP_FLAG_DEBUG); set_flag(listen_sockfd, 1, L2TP_FLAG_CONTROL); /* unknown src and dst addresses */ any_address.sin_len = sizeof(any_address); any_address.sin_family = AF_INET; any_address.sin_port = 0; any_address.sin_addr.s_addr = INADDR_ANY; /* bind the socket in the kernel with L2TP port */ listen_address.sin_len = sizeof(listen_address); listen_address.sin_family = AF_INET; listen_address.sin_port = L2TP_UDP_PORT; listen_address.sin_addr.s_addr = INADDR_ANY; l2tp_set_ouraddress(listen_sockfd, (struct sockaddr *)&listen_address); our_address = listen_address; /* add security policies */ if (!opt_noipsec) { if (configure_racoon(&our_address, &any_address, 0, IPPROTO_UDP, opt_ipsecsharedsecret, opt_ipsecsharedsecrettype) || require_secure_transport((struct sockaddr *)&any_address, (struct sockaddr *)&listen_address, IPPROTO_UDP, "in")) { vpnlog(LOG_ERR, "VPND L2TP plugin: cannot configure secure transport...\n"); return -1; } /* set IPSec Key management to prefer most recent key */ if (set_key_preference(&key_preference, 0)) vpnlog(LOG_ERR, "VPND L2TP plugin: cannot set IPSec Key management preference (error %d)\n", errno); secure_transport = 1; } return listen_sockfd; }
/* ----------------------------------------------------------------------------- l2tpvpn_listen - called by vpnd to setup listening socket ----------------------------------------------------------------------------- */ int l2tpvpn_listen(void) { char *errstr; if (listen_sockfd <= 0) return -1; //set_flag(listen_sockfd, kerneldebug & 1, L2TP_FLAG_DEBUG); set_flag(listen_sockfd, 1, L2TP_FLAG_CONTROL); set_flag(listen_sockfd, !opt_noipsec, L2TP_FLAG_IPSEC); /* unknown src and dst addresses */ any_address.sin_len = sizeof(any_address); any_address.sin_family = AF_INET; any_address.sin_port = 0; any_address.sin_addr.s_addr = INADDR_ANY; /* bind the socket in the kernel with L2TP port */ listen_address.sin_len = sizeof(listen_address); listen_address.sin_family = AF_INET; listen_address.sin_port = htons(L2TP_UDP_PORT); listen_address.sin_addr.s_addr = INADDR_ANY; l2tp_set_ouraddress(listen_sockfd, (struct sockaddr *)&listen_address); our_address = listen_address; /* add security policies */ if (!opt_noipsec) { CFStringRef auth_method; CFStringRef string; CFDataRef data; uint32_t natt_multiple_users; /* get authentication method from the IPSec dict */ auth_method = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecAuthenticationMethod); if (!isString(auth_method)) auth_method = kRASValIPSecAuthenticationMethodSharedSecret; /* get setting for nat traversal multiple user support - default is enabled for server */ GetIntFromDict(ipsec_settings, kRASPropIPSecNattMultipleUsersEnabled, &natt_multiple_users, 1); ipsec_dict = IPSecCreateL2TPDefaultConfiguration( (struct sockaddr *)&our_address, (struct sockaddr *)&any_address, NULL, auth_method, 0, natt_multiple_users, 0); /* set the authentication information */ if (CFEqual(auth_method, kRASValIPSecAuthenticationMethodSharedSecret)) { string = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecSharedSecret); if (isString(string)) CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecret, string); else if (isData(string) && ((CFDataGetLength((CFDataRef)string) % sizeof(UniChar)) == 0)) { CFStringEncoding encoding; data = (CFDataRef)string; #if __BIG_ENDIAN__ encoding = (*(CFDataGetBytePtr(data) + 1) == 0x00) ? kCFStringEncodingUTF16LE : kCFStringEncodingUTF16BE; #else // __LITTLE_ENDIAN__ encoding = (*(CFDataGetBytePtr(data) ) == 0x00) ? kCFStringEncodingUTF16BE : kCFStringEncodingUTF16LE; #endif string = CFStringCreateWithBytes(NULL, (const UInt8 *)CFDataGetBytePtr(data), CFDataGetLength(data), encoding, FALSE); CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecret, string); CFRelease(string); } string = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecSharedSecretEncryption); if (isString(string)) CFDictionarySetValue(ipsec_dict, kRASPropIPSecSharedSecretEncryption, string); } else if (CFEqual(auth_method, kRASValIPSecAuthenticationMethodCertificate)) { data = CFDictionaryGetValue(ipsec_settings, kRASPropIPSecLocalCertificate); if (isData(data)) CFDictionarySetValue(ipsec_dict, kRASPropIPSecLocalCertificate, data); } if (IPSecApplyConfiguration(ipsec_dict, &errstr) || IPSecInstallPolicies(ipsec_dict, -1, &errstr)) { vpnlog(LOG_ERR, "L2TP plugin: cannot configure secure transport (%s).\n", errstr); IPSecRemoveConfiguration(ipsec_dict, &errstr); CFRelease(ipsec_dict); ipsec_dict = 0; return -1; } /* set IPSec Key management to prefer most recent key */ if (IPSecSetSecurityAssociationsPreference(&key_preference, 0)) vpnlog(LOG_ERR, "L2TP plugin: cannot set IPSec Key management preference (error %d)\n", errno); sick_timeleft = IPSEC_SICK_TIME; ping_timeleft = 0; } return listen_sockfd; }