diff options
Diffstat (limited to 'src/pluto/virtual.c')
-rw-r--r-- | src/pluto/virtual.c | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/src/pluto/virtual.c b/src/pluto/virtual.c deleted file mode 100644 index 3e8d5fcba..000000000 --- a/src/pluto/virtual.c +++ /dev/null @@ -1,325 +0,0 @@ -/* FreeS/WAN Virtual IP Management - * Copyright (C) 2002 Mathieu Lafon - Arkoon Network Security - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - */ - -#include <freeswan.h> - -#include <stdlib.h> -#include <string.h> -#include <sys/queue.h> - -#include "constants.h" -#include "defs.h" -#include "log.h" -#include "connections.h" -#include "whack.h" -#include "virtual.h" - -#define F_VIRTUAL_NO 1 -#define F_VIRTUAL_DHCP 2 -#define F_VIRTUAL_IKE_CONFIG 4 -#define F_VIRTUAL_PRIVATE 8 -#define F_VIRTUAL_ALL 16 -#define F_VIRTUAL_HOST 32 - -struct virtual_t { - unsigned short flags; - unsigned short n_net; - ip_subnet net[0]; -}; - -static ip_subnet *private_net_ok=NULL, *private_net_ko=NULL; -static unsigned short private_net_ok_len=0, private_net_ko_len=0; - -/** - * read %v4:x.x.x.x/y or %v6:xxxxxxxxx/yy - * or %v4:!x.x.x.x/y if dstko not NULL - */ -static bool -_read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko, - bool *isok) -{ - bool ok; - int af; - - if ((len > 4) && (strneq(src, "%v4:", 4))) - { - af = AF_INET; - } - else if ((len > 4) && (strneq(src, "%v6:", 4))) - { - af = AF_INET6; - } - else - { - return FALSE; - } - - ok = (src[4] != '!'); - src += ok ? 4 : 5; - len -= ok ? 4 : 5; - - if (!len) - return FALSE; - if (!ok && !dstko) - return FALSE; - - passert ( ((ok)?(dst):(dstko))!=NULL ); - - if (ttosubnet(src, len, af, ((ok)?(dst):(dstko)))) - { - return FALSE; - } - if (isok) - *isok = ok; - return TRUE; -} - -void -init_virtual_ip(const char *private_list) -{ - const char *next, *str=private_list; - unsigned short ign = 0, i_ok, i_ko; - ip_subnet sub; - bool ok; - - /** Count **/ - private_net_ok_len=0; - private_net_ko_len=0; - - while (str) - { - next = strchr(str,','); - if (!next) - next = str + strlen(str); - if (_read_subnet(str, next-str, &sub, &sub, &ok)) - if (ok) - private_net_ok_len++; - else - private_net_ko_len++; - else - ign++; - str = *next ? next+1 : NULL; - } - - if (!ign) - { - /** Allocate **/ - if (private_net_ok_len) - { - private_net_ok = (ip_subnet *)malloc(private_net_ok_len * sizeof(ip_subnet)); - } - if (private_net_ko_len) - { - private_net_ko = (ip_subnet *)malloc(private_net_ko_len * sizeof(ip_subnet)); - } - if ((private_net_ok_len && !private_net_ok) - || (private_net_ko_len && !private_net_ko)) - { - loglog(RC_LOG_SERIOUS, - "can't alloc in init_virtual_ip"); - free(private_net_ok); - private_net_ok = NULL; - free(private_net_ko); - private_net_ko = NULL; - } - else - { - /** Fill **/ - str = private_list; - i_ok = 0; - i_ko = 0; - - while (str) - { - next = strchr(str,','); - if (!next) - next = str + strlen(str); - if (_read_subnet(str, next-str, - &(private_net_ok[i_ok]), &(private_net_ko[i_ko]), &ok)) - { - if (ok) - i_ok++; - else - i_ko++; - } - str = *next ? next+1 : NULL; - } - } - } - else - loglog(RC_LOG_SERIOUS, - "%d bad entries in virtual_private - none loaded", ign); -} - -/** - * virtual string must be : - * {vhost,vnet}:[%method]* - * - * vhost = accept only a host (/32) - * vnet = accept any network - * - * %no = no virtual IP (accept public IP) - * %dhcp = accept DHCP SA (0.0.0.0/0) of affected IP [not implemented] - * %ike = accept affected IKE Config Mode IP [not implemented] - * %priv = accept system-wide private net list - * %v4:x = accept ipv4 in list 'x' - * %v6:x = accept ipv6 in list 'x' - * %all = accept all ips [only for testing] - * - * ex: vhost:%no,%dhcp,%priv,%v4:192.168.1.0/24 - */ -struct virtual_t -*create_virtual(const connection_t *c, const char *string) -{ - unsigned short flags=0, n_net=0, i; - const char *str = string, *next, *first_net=NULL; - ip_subnet sub; - struct virtual_t *v; - - if (!string || string[0] == '\0') - return NULL; - - if (strlen(string) >= 6 && strneq(string,"vhost:",6)) - { - flags |= F_VIRTUAL_HOST; - str += 6; - } - else if (strlen(string) >= 5 && strneq(string,"vnet:",5)) - str += 5; - else - goto fail; - - /** - * Parse string : fill flags & count subnets - */ - while ((str) && (*str)) - { - next = strchr(str,','); - if (!next) next = str + strlen(str); - if (next-str == 3 && strneq(str, "%no", 3)) - flags |= F_VIRTUAL_NO; -#if 0 - else if (next-str == 4 && strneq(str, "%ike", 4)) - flags |= F_VIRTUAL_IKE_CONFIG; - else if (next-str == 5 && strneq(str, "%dhcp", 5)) - flags |= F_VIRTUAL_DHCP; -#endif - else if (next-str == 5 && strneq(str, "%priv", 5)) - flags |= F_VIRTUAL_PRIVATE; - else if (next-str == 4 && strneq(str, "%all", 4)) - flags |= F_VIRTUAL_ALL; - else if (_read_subnet(str, next-str, &sub, NULL, NULL)) - { - n_net++; - if (!first_net) - first_net = str; - } - else - goto fail; - - str = *next ? next+1 : NULL; - } - - v = (struct virtual_t *)malloc(sizeof(struct virtual_t) + - (n_net * sizeof(ip_subnet))); - if (!v) goto fail; - - v->flags = flags; - v->n_net = n_net; - if (n_net && first_net) - { - /** - * Save subnets in newly allocated struct - */ - for (str = first_net, i = 0; str && *str; ) - { - next = strchr(str,','); - if (!next) next = str + strlen(str); - if (_read_subnet(str, next-str, &(v->net[i]), NULL, NULL)) - i++; - str = *next ? next+1 : NULL; - } - } - - return v; - -fail: - plog("invalid virtual string [%s] - " - "virtual selection disabled for connection '%s'", string, c->name); - return NULL; -} - -bool -is_virtual_end(const struct end *that) -{ - return ((that->virt)?TRUE:FALSE); -} - -bool -is_virtual_connection(const connection_t *c) -{ - return ((c->spd.that.virt)?TRUE:FALSE); -} - -static bool net_in_list(const ip_subnet *peer_net, const ip_subnet *list, - unsigned short len) -{ - unsigned short i; - - if (!list || !len) - return FALSE; - - for (i = 0; i < len; i++) - { - if (subnetinsubnet(peer_net, &(list[i]))) - return TRUE; - } - return FALSE; -} - -bool is_virtual_net_allowed(const connection_t *c, const ip_subnet *peer_net, - const ip_address *his_addr) -{ - if (c->spd.that.virt == NULL) - return FALSE; - - if ((c->spd.that.virt->flags & F_VIRTUAL_HOST) - && !subnetishost(peer_net)) - return FALSE; - - if ((c->spd.that.virt->flags & F_VIRTUAL_NO) - && subnetishost(peer_net) && addrinsubnet(his_addr, peer_net)) - return TRUE; - - if ((c->spd.that.virt->flags & F_VIRTUAL_PRIVATE) - && net_in_list(peer_net, private_net_ok, private_net_ok_len) - && !net_in_list(peer_net, private_net_ko, private_net_ko_len)) - return TRUE; - - if (c->spd.that.virt->n_net - && net_in_list(peer_net, c->spd.that.virt->net, c->spd.that.virt->n_net)) - return TRUE; - - if (c->spd.that.virt->flags & F_VIRTUAL_ALL) - { - /** %all must only be used for testing - log it **/ - loglog(RC_LOG_SERIOUS, "Warning - " - "v%s:%%all must only be used for testing", - (c->spd.that.virt->flags & F_VIRTUAL_HOST) ? "host" : "net"); - return TRUE; - } - - return FALSE; -} - |