Ejemplo n.º 1
0
//-----------------------------------------------------------------------------
//	builtin ipsec listen
//-----------------------------------------------------------------------------
static int plugin_listen()
{
	int err;
	char *errstr;
	
     /* add security policies */
	err = IPSecApplyConfiguration(ipsec_conf, &errstr);
	if (err) {
		vpnlog(LOG_ERR, "IPSec plugin: cannot configure racoon files (%s)...\n", errstr);
		return -1;
	}

	err = IPSecInstallPolicies(ipsec_conf, -1, &errstr);
	if (err) {
		vpnlog(LOG_ERR, "IPSec plugin: cannot configure kernel policies (%s)...\n", errstr);
		IPSecRemoveConfiguration(ipsec_conf, &errstr);
		return -1;
	}

	/* set IPSec Key management to prefer most recent key */
	if (IPSecSetSecurityAssociationsPreference(&key_preference, 0))
		vpnlog(LOG_ERR, "IPSec plugin: cannot set IPSec Key management preference (error %d)\n", errno);


	secure_transport = 1;

    return 0;
}
Ejemplo n.º 2
0
//-----------------------------------------------------------------------------
//	process_interface_prefs
//-----------------------------------------------------------------------------
static int process_interface_prefs(struct vpn_params *params)
{
    CFStringRef 	str = 0;
    CFDictionaryRef	dict;
       
    //  get type/subtype of server
    dict = CFDictionaryGetValue(params->serverRef, kRASEntInterface);
    if (!isDictionary(dict)) {
		vpnlog(LOG_ERR, "No Interface dictionary found\n");
		return -1;
	}
		
	str  = CFDictionaryGetValue(dict, kRASPropInterfaceType);		
	if (!isString(str)) {
		vpnlog(LOG_ERR, "No Interface type found\n");
		return -1;
	}
		
	if (CFStringCompare(str, kRASValInterfaceTypePPP, 0) == kCFCompareEqualTo)
		params->server_type = SERVER_TYPE_PPP;
	else if (CFStringCompare(str, kRASValInterfaceTypeIPSec, 0) == kCFCompareEqualTo)
		params->server_type = SERVER_TYPE_IPSEC;
	else {
		vpnlog(LOG_ERR, "Incorrect server type found\n");
		return -1;
	}
	
	return 0;
}
Ejemplo n.º 3
0
/* -----------------------------------------------------------------------------
plugin entry point, called by vpnd
ref is the vpn bundle reference
pppref is the ppp bundle reference
bundles can be layout in two different ways
- As simple vpn bundles (bundle.vpn). the bundle contains the vpn bundle binary.
- As full ppp bundles (bundle.ppp). The bundle contains the ppp bundle binary, 
and also the vpn kext and the vpn bundle binary in its Plugins directory.
if a simple vpn bundle was used, pppref will be NULL.
if a ppp bundle was used, the vpn plugin will be able to get access to the 
Plugins directory and load the vpn kext.
----------------------------------------------------------------------------- */
int start(struct vpn_channel* the_vpn_channel, CFBundleRef ref, CFBundleRef pppref, int debug_mode)
{
    char 	name[MAXPATHLEN]; 
    CFURLRef	url;

    debug = debug_mode;
    
    /* first load the kext if we are loaded as part of a ppp bundle */
    if (pppref) {
        while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
            if (errno != EINTR)
                break;
        if (listen_sockfd < 0) {
            vpnlog(LOG_DEBUG, "first call to socket failed - attempting to load kext\n");
            if (url = CFBundleCopyBundleURL(pppref)) {
                name[0] = 0;
                CFURLGetFileSystemRepresentation(url, 0, name, MAXPATHLEN - 1);
                CFRelease(url);
                strcat(name, "/");
                if (url = CFBundleCopyBuiltInPlugInsURL(pppref)) {
                    CFURLGetFileSystemRepresentation(url, 0, name + strlen(name), 
                                MAXPATHLEN - strlen(name) - strlen(L2TP_NKE) - 1);
                    CFRelease(url);
                    strcat(name, "/");
                    strcat(name, L2TP_NKE);
                    if (!load_kext(name))
                        while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
                            if (errno != EINTR)
                                break;
                }	
            }
            if (listen_sockfd < 0) {
                vpnlog(LOG_ERR, "VPND L2TP plugin: Unable to load L2TP kernel extension\n");
                return -1;
            }
        }
    }
    

    /* retain reference */
    bundle = ref;
    CFRetain(bundle);
    
    pppbundle = pppref;
    CFRetain(pppbundle);
            
    // hookup our socket handlers
    bzero(the_vpn_channel, sizeof(struct vpn_channel));
    the_vpn_channel->get_pppd_args = l2tpvpn_get_pppd_args;
    the_vpn_channel->listen = l2tpvpn_listen;
    the_vpn_channel->accept = l2tpvpn_accept;
    the_vpn_channel->refuse = l2tpvpn_refuse;
    the_vpn_channel->close = l2tpvpn_close;

    return 0;
}
Ejemplo n.º 4
0
/* -----------------------------------------------------------------------------
    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;
}
Ejemplo n.º 5
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* -----------------------------------------------------------------------------
    l2tpvpn_close
----------------------------------------------------------------------------- */
void l2tpvpn_close(void)
{

	char *errstr;
	
	if (racoon_sockfd != -1) {
		close(racoon_sockfd);
		racoon_sockfd = -1;
	}

    if (listen_sockfd != -1) {
        while (close(listen_sockfd) < 0)
            if (errno == EINTR)
                continue;
        listen_sockfd = -1;
    }

    /* remove security policies */
    if (ipsec_dict) {            
        IPSecRemoveConfiguration(ipsec_dict, &errstr);
        IPSecRemovePolicies(ipsec_dict, -1, &errstr);     
        /* restore IPSec Key management preference */
        if (IPSecSetSecurityAssociationsPreference(0, key_preference))
            vpnlog(LOG_ERR, "L2TP plugin: cannot reset IPSec Key management preference (error %d)\n", errno);
		CFRelease(ipsec_dict);
		ipsec_dict = NULL;
    }

	if (ipsec_settings) {
		CFRelease(ipsec_settings);
		ipsec_settings = NULL;
	}

}
Ejemplo n.º 6
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* -----------------------------------------------------------------------------
    l2tpvpn_accept
----------------------------------------------------------------------------- */
int l2tpvpn_accept(void) 
{

    u_int8_t			recv_buf[1500];
    socklen_t				addrlen;
    struct sockaddr_in6		from;
    int 			newSockfd; 
    
    /* we should check if there are too many call from the same IP address 
    in the last xxx minutes, proving a denial of service attack */

    while((newSockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
        if (errno != EINTR) {
            vpnlog(LOG_ERR, "L2TP plugin: Unable to open L2TP socket during accept\n");
            return -1;
        }
    
    /* accept the call. it will copy the data to the new socket */
    //set_flag(newSockfd, kerneldebug & 1, L2TP_FLAG_DEBUG);
    setsockopt(newSockfd, PPPPROTO_L2TP, L2TP_OPT_ACCEPT, 0, 0);
    
    /* read the duplicated SCCRQ from the listen socket and ignore for now */
    if (l2tp_sys_recvfrom(listen_sockfd, recv_buf, 1500, MSG_DONTWAIT, (struct sockaddr*)&from, &addrlen) < 0)
        return -1;
    
    return newSockfd;
}
Ejemplo n.º 7
0
/* -----------------------------------------------------------------------------
    l2tpvpn_refuse - called by vpnd to refuse an incomming connection.
        return values: 	 -1 		error
                         socket#	launch pppd with next server address  
                         0 			handled, do nothing
                        
----------------------------------------------------------------------------- */
int l2tpvpn_refuse(void) 
{
    u_int8_t			recv_buf[1500];
    int				addrlen;
    struct sockaddr_in6		from;    
    int 			newSockfd; 
    
    /* we should check if there are too many call from the same IP address 
    in the last xxx minutes, proving a denial of service attack */

    /* need t read the packet to empty the socket buffer */
    while((newSockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
        if (errno != EINTR) {
            vpnlog(LOG_ERR, "VPND L2TP plugin: Unable to open L2TP socket during refuse\n");
            return -1;
        }
    
    /* accept the call. it will copy the data to the new socket */
    setsockopt(newSockfd, PPPPROTO_L2TP, L2TP_OPT_ACCEPT, 0, 0);
    /* and close it right away */
    close(newSockfd);
    
    /* read the duplicated SCCRQ from the listen socket and ignore for now */
    if (l2tp_sys_recvfrom(listen_sockfd, recv_buf, 1500, MSG_DONTWAIT, (struct sockaddr*)&from, &addrlen) < 0)
        return -1;
    
    return 0;
}
Ejemplo n.º 8
0
/* -----------------------------------------------------------------------------
    l2tpvpn_close
----------------------------------------------------------------------------- */
void l2tpvpn_close(void)
{

    if (listen_sockfd != -1) {
        while (close(listen_sockfd) < 0)
            if (errno == EINTR)
                continue;
        listen_sockfd = -1;
    }

    /* remove security policies */
    if (secure_transport) {            
        cleanup_racoon(&our_address, &any_address);
        remove_secure_transport((struct sockaddr *)&any_address, (struct sockaddr *)&listen_address, IPPROTO_UDP, "in");            
        /* restore IPSec Key management preference */
        if (set_key_preference(0, key_preference))
            vpnlog(LOG_ERR, "VPND L2TP plugin: cannot reset IPSec Key management preference (error %d)\n", errno);
    }

    if (need_stop_racoon) {
        need_stop_racoon = 0;
        // let racoon running
        //stop_racoon();
    }

}
Ejemplo n.º 9
0
int l2tp_sys_setsockopt(int sockfd, int level, int optname, const void *optval, int optlen)
{
    while (setsockopt(sockfd, level, optname, optval, optlen) < 0)
        if (errno != EINTR) {
            vpnlog(LOG_ERR, "VPND L2TP plugin: error calling setsockopt for option %d (%s)\n", optname, strerror(errno));
            return -1;
        }
    return 0;
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
//	builtin ipsec close
//-----------------------------------------------------------------------------
static void plugin_close()
{
	int err;
	char *errstr;

    /* remove security policies */
    if (secure_transport) {            
        err = IPSecRemoveConfiguration(ipsec_conf, &errstr);
		if (err)
			vpnlog(LOG_ERR, "IPSec plugin: cannot remove IPSec configuration (%s)...\n", errstr);
        err = IPSecRemovePolicies(ipsec_conf, -1, &errstr);            
		if (err)
			vpnlog(LOG_ERR, "IPSec plugin: cannot delete kernel policies (%s)...\n", errstr);
		/* restore IPSec Key management preference */
        if (IPSecSetSecurityAssociationsPreference(0, key_preference))
            vpnlog(LOG_ERR, "L2TP plugin: cannot reset IPSec Key management preference (error %d)\n", errno);
    }
}
Ejemplo n.º 11
0
int l2tp_sys_recvfrom(int sockfd, void *buff, size_t nbytes, int flags,
            struct sockaddr *from, int *addrlen)
{
    while (recvfrom(sockfd, buff, nbytes, flags, from, addrlen) < 0)
        if (errno != EINTR) {
            vpnlog(LOG_ERR, "VPND L2TP plugin: error calling recvfrom = %s\n", strerror(errno));
            return -1;
        }
    return 0;
}
Ejemplo n.º 12
0
// ----------------------------------------------------------------------------
//	get_active_server
// ----------------------------------------------------------------------------
CFArrayRef get_active_servers(struct vpn_params *params)
{
    SCPreferencesRef 		prefs = 0;
    CFPropertyListRef		active_servers;
    CFArrayRef                  arrayCopy = 0;
    char 			pathStr[MAXPATHLEN];

    // open the prefs file
    prefs = SCPreferencesCreate(0, CFSTR("vpnd"), kRASServerPrefsFileName);
    if (prefs == NULL) {
        CFStringGetCString(kRASServerPrefsFileName, pathStr, MAXPATHLEN, kCFStringEncodingMacRoman);
        vpnlog(LOG_ERR, "Unable to read vpnd prefs file '%s'\n", pathStr);
        return 0;
    }
    // get active servers list from the plist
    active_servers = SCPreferencesGetValue(prefs, kRASActiveServers);
    if (active_servers && isArray(active_servers))
        if (CFArrayGetCount(active_servers) > 0)
            arrayCopy = CFArrayCreateCopy(0, active_servers);
    CFRelease(prefs);
    return arrayCopy;
}
Ejemplo n.º 13
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* ----------------------------------------------------------------------------- 
    l2tpvpn_health_check
----------------------------------------------------------------------------- */
int l2tpvpn_health_check(int *outfd, int event)
{

	size_t				size;
	struct	sockaddr_un sun;
	int					ret = -1, flags;
	
	char				data[256];
	struct vpnctl_hdr			*hdr = (struct vpnctl_hdr *)data;
	
	switch (event) {
		
		case 0: // periodic check
			
			// no ipsec, no need for health check
			if (opt_noipsec) {
				*outfd = -1;
				break;
			}
	
			if (sick_timeleft) {
				sick_timeleft--;
				if (sick_timeleft == 0)
					goto fail;
			}

			// racoon socket is already opened, just query racoon
			if (racoon_sockfd != -1) {

				if (ping_timeleft) {
					ping_timeleft--;
					if (ping_timeleft == 0) {
						// error on racoon socket. racoon exited ?
						ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover
						sick_timeleft = IPSEC_SICK_TIME;				
						goto fail;
					}
				}
				else {
					// query racoon here
					bzero(hdr, sizeof(struct vpnctl_hdr));
					hdr->msg_type = htons(VPNCTL_CMD_PING);
					hdr->cookie = htonl(++racoon_ping_seed);
					ping_timeleft = IPSEC_PING_TIME;		// give few seconds to get a reply
					writen(racoon_sockfd, hdr, sizeof(struct vpnctl_hdr));
				}
				break;
			}
	
			// attempt to kill and restart racoon every 10 seconds
			if ((sick_timeleft % IPSEC_REPAIR_TIME) == 0) {
				vpnlog(LOG_ERR, "IPSecSelfRepair\n");
				IPSecSelfRepair();
			}
	
			// racoon socket is not yet opened, so opened it
			/* open the racoon control socket  */
			racoon_sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
			if (racoon_sockfd < 0) {
				vpnlog(LOG_ERR, "Unable to create racoon control socket (errno = %d)\n", errno);
				goto fail;
			}

			bzero(&sun, sizeof(sun));
			sun.sun_family = AF_LOCAL;
			strncpy(sun.sun_path, "/var/run/vpncontrol.sock", sizeof(sun.sun_path));

			if (connect(racoon_sockfd,  (struct sockaddr *)&sun, sizeof(sun)) < 0) {
				vpnlog(LOG_ERR, "Unable to connect racoon control socket (errno = %d)\n", errno);
				ret = -2;
				goto fail;
			}

			if ((flags = fcntl(racoon_sockfd, F_GETFL)) == -1
				|| fcntl(racoon_sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
				vpnlog(LOG_ERR, "Unable to set racoon control socket in non-blocking mode (errno = %d)\n", errno);
				ret = -2;
				goto fail;
			}
				
			*outfd = racoon_sockfd;
			sick_timeleft = 0;
			ping_timeleft = 0;
			break;
			
		case 1: // event on racoon fd
			size = recvfrom (racoon_sockfd, data, sizeof(struct vpnctl_hdr), 0, 0, 0);
			if (size == 0) {
				// error on racoon socket. racoon exited ?
				ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover
				sick_timeleft = IPSEC_SICK_TIME;
				ping_timeleft = 0;
				goto fail;
			}
			
			/* read end of packet */
			if (ntohs(hdr->len)) {
				size = recvfrom (racoon_sockfd, data + sizeof(struct vpnctl_hdr), ntohs(hdr->len), 0, 0, 0);
				if (size == 0) {
					// error on racoon socket. racoon exited ?
					ret = -2; // L2TP is sick, but don't die yet, give it 60 seconds to recover
					sick_timeleft = IPSEC_SICK_TIME;
					ping_timeleft = 0;
					goto fail;
				}
			}
			
			switch (ntohs(hdr->msg_type)) {
			
				case VPNCTL_CMD_PING:
				
					if (racoon_ping_seed == ntohl(hdr->cookie)) {
						// good !
						ping_timeleft = 0;
					//vpnlog(LOG_DEBUG, "receive racoon PING REPLY cookie %d\n", ntohl(hdr->cookie));
					}
					break;
					
				default:	
					/* ignore other messages */
					//vpnlog(LOG_DEBUG, "receive racoon message type %d, result %d\n", ntohs(hdr->msg_type), ntohs(hdr->result));
					break;

			}
			break;
		
	}

	return 0;

fail:
	if (racoon_sockfd != -1) {
		close(racoon_sockfd);
		racoon_sockfd = -1;
		*outfd = -1;
	}
	return ret;
}
Ejemplo n.º 14
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* -----------------------------------------------------------------------------
plugin entry point, called by vpnd
ref is the vpn bundle reference
pppref is the ppp bundle reference
bundles can be layout in two different ways
- As simple vpn bundles (bundle.vpn). the bundle contains the vpn bundle binary.
- As full ppp bundles (bundle.ppp). The bundle contains the ppp bundle binary, 
and also the vpn kext and the vpn bundle binary in its Plugins directory.
if a simple vpn bundle was used, pppref will be NULL.
if a ppp bundle was used, the vpn plugin will be able to get access to the 
Plugins directory and load the vpn kext.
----------------------------------------------------------------------------- */
int start(struct vpn_channel* the_vpn_channel, CFBundleRef ref, CFBundleRef pppref, int debug_mode, int log_verbose)
{
    char 	name[MAXPATHLEN]; 
    CFURLRef	url;
    size_t		len; 
	int			nb_cpu = 1, nb_threads = 0;

    debug = debug_mode;
    
    /* first load the kext if we are loaded as part of a ppp bundle */
    if (pppref) {
        while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
            if (errno != EINTR)
                break;
        if (listen_sockfd < 0) {
            vpnlog(LOG_DEBUG, "L2TP plugin: first call to socket failed - attempting to load kext\n");
            if (url = CFBundleCopyBundleURL(pppref)) {
                name[0] = 0;
                CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)name, MAXPATHLEN - 1);
                CFRelease(url);
                strlcat(name, "/", sizeof(name));
                if (url = CFBundleCopyBuiltInPlugInsURL(pppref)) {
                    CFURLGetFileSystemRepresentation(url, 0, (UInt8 *)(name + strlen(name)), 
                                MAXPATHLEN - strlen(name) - strlen(L2TP_NKE) - 1);
                    CFRelease(url);
                    strlcat(name, "/", sizeof(name));
                    strlcat(name, L2TP_NKE, sizeof(name));
#if !TARGET_OS_EMBEDDED // This file is not built for Embedded
                    if (!load_kext(name, 0))
#else
                    if (!load_kext(L2TP_NKE_ID, 1))
#endif
                        while ((listen_sockfd = socket(PF_PPP, SOCK_DGRAM, PPPPROTO_L2TP)) < 0)
                            if (errno != EINTR)
                                break;
                }	
            }
            if (listen_sockfd < 0) {
                vpnlog(LOG_ERR, "L2TP plugin: Unable to load L2TP kernel extension\n");
                return -1;
            }
        }
    }
    
#if !TARGET_OS_EMBEDDED // This file is not built for Embedded
	/* increase the number of threads for l2tp to nb cpus - 1 */
    len = sizeof(int); 
	sysctlbyname("hw.ncpu", &nb_cpu, &len, NULL, 0);
    if (nb_cpu > 1) {
		sysctlbyname("net.ppp.l2tp.nb_threads", &nb_threads, &len, 0, 0);
		if (nb_threads < (nb_cpu - 1)) {
			nb_threads = nb_cpu - 1;
			sysctlbyname("net.ppp.l2tp.nb_threads", 0, 0, &nb_threads, sizeof(int));
		}
	}
#endif

    /* retain reference */
    bundle = ref;
    CFRetain(bundle);
    
    pppbundle = pppref;
    if (pppbundle)
        CFRetain(pppbundle);
            
    // hookup our socket handlers
    bzero(the_vpn_channel, sizeof(struct vpn_channel));
    the_vpn_channel->get_pppd_args = l2tpvpn_get_pppd_args;
    the_vpn_channel->listen = l2tpvpn_listen;
    the_vpn_channel->accept = l2tpvpn_accept;
    the_vpn_channel->refuse = l2tpvpn_refuse;
    the_vpn_channel->close = l2tpvpn_close;
    the_vpn_channel->health_check = l2tpvpn_health_check;
    the_vpn_channel->lb_redirect = l2tpvpn_lb_redirect;

    return 0;
}
Ejemplo n.º 15
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* -----------------------------------------------------------------------------
    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;
}
Ejemplo n.º 16
0
// ----------------------------------------------------------------------------
//	process_prefs
// ----------------------------------------------------------------------------
int ipsec_process_prefs(struct vpn_params *params)
{
	char *errstr, c;
	CFStringRef	string;
	
	if (ipsec_conf) {
		CFRelease(ipsec_conf);
		ipsec_conf = NULL;
	}

	ipsec_conf = (CFMutableDictionaryRef)CFDictionaryGetValue(params->serverRef, kRASEntIPSec);
	if (ipsec_conf == NULL) {
		vpnlog(LOG_ERR, "IPSec plugin: IPSec dictionary not present\n");
		goto fail;
	}
		
	ipsec_conf = CFDictionaryCreateMutableCopy(NULL, 0, ipsec_conf);

	remoteaddress[0] = 0;
	string  = CFDictionaryGetValue(ipsec_conf, kRASPropIPSecRemoteAddress);
	if (isString(string))
		CFStringGetCString(string, remoteaddress, sizeof(remoteaddress), kCFStringEncodingUTF8);

	if (inet_aton(remoteaddress, &peer_address) == 0) {
			
		if (pipe(resolverfds) < 0) {
			vpnlog(LOG_ERR, "IPSec plugin: failed to create pipe for gethostbyname\n");
			goto fail;
		}

		if (pthread_create(&resolverthread, NULL, ipsec_resolver_thread, NULL)) {
			vpnlog(LOG_ERR, "IPSec plugin: failed to create thread for gethostbyname...\n");
			close(resolverfds[0]);
			close(resolverfds[1]);
			goto fail;
		}
		
		while (read(resolverfds[0], &c, 1) != 1) {
			if (got_terminate()) {
				pthread_cancel(resolverthread);
				break;
			}
		}
		
		close(resolverfds[0]);
		close(resolverfds[1]);
		
		if (got_terminate())
			goto fail;
		
		if (c) {
			vpnlog(LOG_ERR, "IPSec plugin: Host '%s' not found...\n", remoteaddress);
			goto fail;
		}
		
		string = CFStringCreateWithCString(0, addr2ascii(AF_INET, &peer_address, sizeof(peer_address), 0), kCFStringEncodingASCII);
		CFDictionarySetValue(ipsec_conf, kRASPropIPSecRemoteAddress, string);
		CFRelease(string);
	}

	// verify the dictionary
	if (IPSecValidateConfiguration(ipsec_conf, &errstr)) {

		vpnlog(LOG_ERR, "IPSec plugin: Incorrect preferences (%s)\n", errstr);
		goto fail;
	}
	
    return 0;

fail:
	if (ipsec_conf) {
		CFRelease(ipsec_conf);
		ipsec_conf = NULL;
	}
    return -1;
}
Ejemplo n.º 17
0
Archivo: main.c Proyecto: TARRANUM/ppp
/* ----------------------------------------------------------------------------- 
    l2tpvpn_get_pppd_args
----------------------------------------------------------------------------- */
int l2tpvpn_get_pppd_args(struct vpn_params *params, int reload)
{

    CFStringRef	string;
    int		noipsec = 0;
    CFMutableDictionaryRef	dict = NULL;
	
    if (reload) {
        noipsec = opt_noipsec;
    }
    
    if (params->serverRef) {			
        /* arguments from the preferences file */
        addstrparam(params->exec_args, &params->next_arg_index, "l2tpmode", "answer");

        string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPTransport);
        if (string && CFEqual(string, kRASValL2TPTransportIP)) {
            addparam(params->exec_args, &params->next_arg_index, "l2tpnoipsec");
            opt_noipsec = 1;
        }
			
		dict = (CFMutableDictionaryRef)CFDictionaryGetValue(params->serverRef, kRASEntIPSec);
		if (isDictionary(dict)) {
			/* get the parameters from the IPSec dictionary */
			dict = CFDictionaryCreateMutableCopy(0, 0, dict);
		}
		else {
			/* get the parameters from the L2TP dictionary */
			dict = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
			
			string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPIPSecSharedSecretEncryption);
			if (isString(string))
				CFDictionarySetValue(dict, kRASPropIPSecSharedSecretEncryption, string);

			string = get_cfstr_option(params->serverRef, kRASEntL2TP, kRASPropL2TPIPSecSharedSecret);
			if (isString(string))
				CFDictionarySetValue(dict, kRASPropIPSecSharedSecret, string);
		}

    } else {
        /* arguments from command line */
        if (opt_noipsec)
            addparam(params->exec_args, &params->next_arg_index, "l2tpnoipsec");
    }
    
    if (reload) {
        if (noipsec != opt_noipsec ||
            !CFEqual(dict, ipsec_settings)) {
				vpnlog(LOG_ERR, "reload prefs - IPSec shared secret cannot be changed\n");
				if (dict)
					CFRelease(dict);
				return -1;
		}
    }

	if (ipsec_settings) 
		CFRelease(ipsec_settings);
	ipsec_settings = dict;
	
    return 0;
}
Ejemplo n.º 18
0
// ----------------------------------------------------------------------------
//	process_prefs
// ----------------------------------------------------------------------------
int process_prefs(struct vpn_params *params)
{

    char 			pathStr[MAXPATHLEN];
    SCPreferencesRef 		prefs = 0;
    CFPropertyListRef		servers_list;
    
    char 			text[512] = "";
  
    // open the prefs file
    prefs = SCPreferencesCreate(0, CFSTR("vpnd"), kRASServerPrefsFileName);
    if (prefs == NULL) {
        CFStringGetCString(kRASServerPrefsFileName, pathStr, MAXPATHLEN, kCFStringEncodingMacRoman);
        snprintf(text, sizeof(text), "Unable to read vpnd prefs file '%s'\n", pathStr);
        goto fail;
    }
    // get servers list from the plist
    servers_list = SCPreferencesGetValue(prefs, kRASServers);
    if (servers_list == NULL) {
        snprintf(text, sizeof(text), "Could not get servers dictionary\n");
        goto fail;
    }
    // retrieve the information for the given Server ID
    params->serverIDRef = CFStringCreateWithCString(0, params->server_id, kCFStringEncodingMacRoman);
    if (params->serverIDRef == NULL) {
        snprintf(text, sizeof(text), "Could not create CFString for server ID\n");
        goto fail;
    }
    params->serverRef = CFDictionaryGetValue(servers_list, params->serverIDRef);
    if (params->serverRef == NULL || isDictionary(params->serverRef) == 0) {
        snprintf(text, sizeof(text), "Server ID '%.64s' invalid\n", params->server_id);
        params->serverRef = 0;
        goto fail;
    }
    CFRetain(params->serverRef);
    CFRelease(prefs);
    prefs = 0;    
    
    // process the dictionaries
    if (process_server_prefs(params))
        goto fail;
    if (process_interface_prefs(params))
        goto fail;
	
	switch (params->server_type) {
		case SERVER_TYPE_PPP:
			if (ppp_process_prefs(params)) {
				snprintf(text, sizeof(text), "Error while reading PPP preferences\n");
				goto fail;
			}
			break;
		case SERVER_TYPE_IPSEC:
			if (ipsec_process_prefs(params)) {
				snprintf(text, sizeof(text), "Error while reading IPSec preferences\n");
				goto fail;
			}
			break;
	}

    return 0;

fail:
    vpnlog(LOG_ERR, text[0] ? text : "Error while reading preferences\n");
    if (params->serverIDRef) {
        CFRelease(params->serverIDRef);
        params->serverIDRef = 0;
    }
    if (params->serverRef) {
        CFRelease(params->serverRef);
        params->serverRef = 0;
    }
    if (prefs)
        CFRelease(prefs);
    return -1;
}
Ejemplo n.º 19
0
//-----------------------------------------------------------------------------
//	process_server_prefs
//-----------------------------------------------------------------------------
static int process_server_prefs(struct vpn_params *params)
{
    u_int32_t		lval, len;
    u_char            str[MAXPATHLEN];   
	int				err ;
	struct hostent	*hostent;
	
    get_int_option(params->serverRef, kRASEntServer, kRASPropServerMaximumSessions, &lval, 0);
    if (lval)
        params->max_sessions = lval;
	len = sizeof(str);
    get_str_option(params->serverRef, kRASEntServer, kRASPropServerLogfile, str, sizeof(str), &len, (u_char*)default_log_path);
    if (str[0])
        memcpy(params->log_path, str, len + 1);

    get_int_option(params->serverRef, kRASEntServer, kRASPropServerVerboseLogging, &lval, 0);
    if (lval)
        params->log_verbose = lval;

	// Load balancing parameters
	get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingEnabled, &lval, 0);
	if (lval) {
		params->lb_enable = 1;
		
		// will determine the interface from the cluster address
		//len = sizeof(str);
		//get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingInterface, str, sizeof(str), &len, "en1");
		//strncpy(params->lb_interface, str, sizeof(params->lb_interface));

		// is priority really useful ?
		//get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPriority, &lval, 5);
		//if (lval < 1) lval = 1;
		//else if (lval > LB_MAX_PRIORITY) lval = LB_MAX_PRIORITY;
		//params->lb_priority = lval;
		
		get_int_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingPort, &lval, LB_DEFAULT_PORT);
		params->lb_port = htons(lval);
		len = sizeof(str);
		get_str_option(params->serverRef, kRASEntServer, kRASPropServerLoadBalancingAddress, str, sizeof(str), &len, empty_str);
		// ask the system to look up the given name.
		hostent = getipnodebyname ((char*)str, AF_INET, 0, &err);
		if (!hostent) {
			vpnlog(LOG_ERR, "Incorrect Load Balancing address found '%s'\n", str);
			params->lb_enable = 0;
			
		}
		else {
			struct sockaddr_in src, dst;
			
			params->lb_cluster_address = *(struct in_addr *)hostent->h_addr_list[0];
			freehostent(hostent);
			
			bzero(&dst, sizeof(dst));
			dst.sin_family = PF_INET;
			dst.sin_len = sizeof(dst);
			dst.sin_addr = params->lb_cluster_address;
		
			// look for the interface and primary address of the cluster address			
			if (get_route_interface((struct sockaddr *)&src, (struct sockaddr *)&dst, params->lb_interface)) {
			
				vpnlog(LOG_ERR, "Cannot get load balancing redirect address and interface (errno = %d)\n", errno);
				params->lb_enable = 0;
			}

			params->lb_redirect_address = src.sin_addr;

			
		}
	}
	
    return 0;
}