refactoring of Mode Config functionality allows transport and handling of any attribute

This commit is contained in:
Andreas Steffen 2010-05-14 17:07:03 +02:00
parent a273546854
commit 03b5e4d8d7
10 changed files with 739 additions and 742 deletions

7
NEWS
View File

@ -1,3 +1,10 @@
strongswan-4.4.1
----------------
- The major refactoring of the IKEv1 Mode Config functionality now allows
the transport and handling of any Mode Config attribute.
strongswan-4.4.0
----------------

View File

@ -36,8 +36,31 @@ ENUM_BEGIN(configuration_attribute_type_names, INTERNAL_IP4_ADDRESS, INTERNAL_IP
"MIP6_HOME_PREFIX",
"INTERNAL_IP6_LINK",
"INTERNAL_IP6_PREFIX");
ENUM_NEXT(configuration_attribute_type_names, INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, INTERNAL_IP6_PREFIX,
ENUM_NEXT(configuration_attribute_type_names, XAUTH_TYPE, XAUTH_ANSWER, INTERNAL_IP6_PREFIX,
"XAUTH_TYPE",
"XAUTH_USER_NAME",
"XAUTH_USER_PASSWORD",
"XAUTH_PASSCODE",
"XAUTH_MESSAGE",
"XAUTH_CHALLENGE",
"XAUTH_DOMAIN",
"XAUTH_STATUS",
"XAUTH_NEXT_PIN",
"XAUTH_ANSWER");
ENUM_NEXT(configuration_attribute_type_names, INTERNAL_IP4_SERVER, INTERNAL_IP6_SERVER, XAUTH_ANSWER,
"INTERNAL_IP4_SERVER",
"INTERNAL_IP6_SERVER");
ENUM_END(configuration_attribute_type_names, INTERNAL_IP6_SERVER);
ENUM_NEXT(configuration_attribute_type_names, UNITY_BANNER, UNITY_DDNS_HOSTNAME, INTERNAL_IP6_SERVER,
"UNITY_BANNER",
"UNITY_SAVE_PASSWD",
"UNITY_DEF_DOMAIN",
"UNITY_SPLITDNS_NAME",
"UNITY_SPLIT_INCLUDE",
"UNITY_NATT_PORT",
"UNITY_LOCAL_LAN",
"UNITY_PFS",
"UNITY_FW_TYPE",
"UNITY_BACKUP_SERVERS",
"UNITY_DDNS_HOSTNAME");
ENUM_END(configuration_attribute_type_names, UNITY_DDNS_HOSTNAME);

View File

@ -30,27 +30,50 @@ typedef enum configuration_attribute_type_t configuration_attribute_type_t;
* Type of the attribute, as in IKEv2 RFC 3.15.1 or IKEv1 ModeConfig.
*/
enum configuration_attribute_type_t {
INTERNAL_IP4_ADDRESS = 1,
INTERNAL_IP4_NETMASK = 2,
INTERNAL_IP4_DNS = 3,
INTERNAL_IP4_NBNS = 4,
INTERNAL_IP4_ADDRESS = 1,
INTERNAL_IP4_NETMASK = 2,
INTERNAL_IP4_DNS = 3,
INTERNAL_IP4_NBNS = 4,
INTERNAL_ADDRESS_EXPIRY = 5,
INTERNAL_IP4_DHCP = 6,
APPLICATION_VERSION = 7,
INTERNAL_IP6_ADDRESS = 8,
INTERNAL_IP6_NETMASK = 9,
INTERNAL_IP6_DNS = 10,
INTERNAL_IP6_NBNS = 11,
INTERNAL_IP6_DHCP = 12,
INTERNAL_IP4_SUBNET = 13,
SUPPORTED_ATTRIBUTES = 14,
INTERNAL_IP6_SUBNET = 15,
MIP6_HOME_PREFIX = 16,
INTERNAL_IP6_LINK = 17,
INTERNAL_IP6_PREFIX = 18,
INTERNAL_IP4_DHCP = 6,
APPLICATION_VERSION = 7,
INTERNAL_IP6_ADDRESS = 8,
INTERNAL_IP6_NETMASK = 9,
INTERNAL_IP6_DNS = 10,
INTERNAL_IP6_NBNS = 11,
INTERNAL_IP6_DHCP = 12,
INTERNAL_IP4_SUBNET = 13,
SUPPORTED_ATTRIBUTES = 14,
INTERNAL_IP6_SUBNET = 15,
MIP6_HOME_PREFIX = 16,
INTERNAL_IP6_LINK = 17,
INTERNAL_IP6_PREFIX = 18,
/* XAUTH attributes */
XAUTH_TYPE = 16520,
XAUTH_USER_NAME = 16521,
XAUTH_USER_PASSWORD = 16522,
XAUTH_PASSCODE = 16523,
XAUTH_MESSAGE = 16524,
XAUTH_CHALLENGE = 16525,
XAUTH_DOMAIN = 16526,
XAUTH_STATUS = 16527,
XAUTH_NEXT_PIN = 16528,
XAUTH_ANSWER = 16529,
/* proprietary Microsoft attributes */
INTERNAL_IP4_SERVER = 23456,
INTERNAL_IP6_SERVER = 23457
INTERNAL_IP4_SERVER = 23456,
INTERNAL_IP6_SERVER = 23457,
/* proprietary Cisco Unity attributes */
UNITY_BANNER = 28672,
UNITY_SAVE_PASSWD = 28673,
UNITY_DEF_DOMAIN = 28674,
UNITY_SPLITDNS_NAME = 28675,
UNITY_SPLIT_INCLUDE = 28676,
UNITY_NATT_PORT = 28677,
UNITY_LOCAL_LAN = 28678,
UNITY_PFS = 28679,
UNITY_FW_TYPE = 28680,
UNITY_BACKUP_SERVERS = 28681,
UNITY_DDNS_HOSTNAME = 28682
};
/**

View File

@ -369,14 +369,10 @@ void delete_connection(connection_t *c, bool relations)
/* release virtual IP address lease if any */
if (c->spd.that.modecfg && c->spd.that.pool &&
!isanyaddr(&c->spd.that.host_srcip))
!c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip))
{
host_t *vip;
vip = host_create_from_sockaddr((sockaddr_t*)&c->spd.that.host_srcip);
hydra->attributes->release_address(hydra->attributes, c->spd.that.pool,
vip, c->spd.that.id);
vip->destroy(vip);
c->spd.that.host_srcip, c->spd.that.id);
}
/* release requested attributes if any */
@ -411,11 +407,14 @@ void delete_connection(connection_t *c, bool relations)
DESTROY_IF(c->spd.this.id);
DESTROY_IF(c->spd.this.ca);
DESTROY_IF(c->spd.this.groups);
DESTROY_IF(c->spd.this.host_srcip);
free(c->spd.this.updown);
free(c->spd.this.pool);
DESTROY_IF(c->spd.that.id);
DESTROY_IF(c->spd.that.ca);
DESTROY_IF(c->spd.that.groups);
DESTROY_IF(c->spd.that.host_srcip);
free(c->spd.that.updown);
free(c->spd.that.pool);
if (c->requested_ca)
@ -678,7 +677,7 @@ size_t format_end(char *buf, size_t buf_len, const struct end *this,
subnettot(&this->client, 0, client, sizeof(client));
}
}
else if (this->modecfg && isanyaddr(&this->host_srcip))
else if (this->modecfg && this->host_srcip->is_anyaddr(this->host_srcip))
{
/* we are mode config client, or a server with a pool */
client_sep = "===";
@ -763,6 +762,7 @@ static void unshare_connection_strings(connection_t *c)
c->spd.this.id = c->spd.this.id->clone(c->spd.this.id);
c->spd.this.pool = clone_str(c->spd.this.pool);
c->spd.this.updown = clone_str(c->spd.this.updown);
c->spd.this.host_srcip = c->spd.this.host_srcip->clone(c->spd.this.host_srcip);
scx_share(c->spd.this.sc);
cert_share(c->spd.this.cert);
if (c->spd.this.ca)
@ -776,6 +776,7 @@ static void unshare_connection_strings(connection_t *c)
c->spd.that.id = c->spd.that.id->clone(c->spd.that.id);
c->spd.that.pool = clone_str(c->spd.that.pool);
c->spd.that.updown = clone_str(c->spd.that.updown);
c->spd.that.host_srcip = c->spd.that.host_srcip->clone(c->spd.that.host_srcip);
scx_share(c->spd.that.sc);
cert_share(c->spd.that.cert);
if (c->spd.that.ca)
@ -924,7 +925,7 @@ static bool extract_end(struct end *dst, const whack_end_t *src,
/* the rest is simple copying of corresponding fields */
dst->host_addr = src->host_addr;
dst->host_nexthop = src->host_nexthop;
dst->host_srcip = src->host_srcip;
dst->host_srcip = host_create_from_sockaddr((sockaddr_t*)&src->host_srcip);
dst->has_natip = src->has_natip;
dst->client = src->client;
dst->protocol = src->protocol;
@ -949,10 +950,14 @@ static bool extract_end(struct end *dst, const whack_end_t *src,
/* if host sourceip is defined but no client is present
* behind the host then set client to sourceip/32
*/
if (addrbytesptr(&dst->host_srcip, NULL) &&
!isanyaddr(&dst->host_srcip) && !dst->has_natip && !dst->has_client)
if (!dst->host_srcip->is_anyaddr(dst->host_srcip) &&
!dst->has_natip && !dst->has_client)
{
err_t ugh = addrtosubnet(&dst->host_srcip, &dst->client);
ip_address addr;
err_t ugh;
addr = *(ip_address*)dst->host_srcip->get_sockaddr(dst->host_srcip);
ugh = addrtosubnet(&addr, &dst->client);
if (ugh)
{
@ -1233,7 +1238,8 @@ void add_connection(const whack_message_t *wm)
c->spd.that.modecfg = TRUE;
c->spd.that.has_client = FALSE;
/* reset the host_srcip so that it gets assigned in modecfg */
anyaddr(AF_INET, &c->spd.that.host_srcip);
DESTROY_IF(c->spd.that.host_srcip);
c->spd.that.host_srcip = host_create_any(AF_INET);
}
if (c->ikev1)
@ -3068,7 +3074,8 @@ void ISAKMP_SA_established(connection_t *c, so_serial_t serial)
/* the connection is now oriented so that we are able to determine
* whether we are a mode config server with a virtual IP to send.
*/
if (!isanyaddr(&c->spd.that.host_srcip) && !c->spd.that.has_natip)
if (!c->spd.that.host_srcip->is_anyaddr(c->spd.that.host_srcip) &&
!c->spd.that.has_natip)
{
c->spd.that.modecfg = TRUE;
}
@ -3715,8 +3722,10 @@ static connection_t *fc_try(const connection_t *c, struct host_pair *hp,
}
else
{
host_t *vip = c->spd.that.host_srcip;
if (!peer_net_is_host && !(sr->that.modecfg && c->spd.that.modecfg &&
subnetisaddr(peer_net, &c->spd.that.host_srcip)))
subnetisaddr(peer_net, (ip_address*)vip->get_sockaddr(vip))))
{
continue;
}

View File

@ -1,6 +1,6 @@
/* information about connections between hosts and clients
* Copyright (C) 1998-2001 D. Hugh Redelmeier
* Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
* Copyright (C) 2009-2010 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* 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
@ -18,6 +18,7 @@
#include <sys/queue.h>
#include <utils/host.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
#include <credentials/ietf_attributes/ietf_attributes.h>
@ -131,10 +132,8 @@ struct virtual_t;
struct end {
identification_t *id;
ip_address
host_addr,
host_nexthop,
host_srcip;
ip_address host_addr, host_nexthop;
host_t *host_srcip;
ip_subnet client;
bool is_left;

View File

@ -543,41 +543,6 @@ extern enum_names attr_msg_type_names;
extern enum_names modecfg_attr_names;
/* XAUTH attribute values */
#define XAUTH_TYPE 16520
#define XAUTH_USER_NAME 16521
#define XAUTH_USER_PASSWORD 16522
#define XAUTH_PASSCODE 16523
#define XAUTH_MESSAGE 16524
#define XAUTH_CHALLENGE 16525
#define XAUTH_DOMAIN 16526
#define XAUTH_STATUS 16527
#define XAUTH_NEXT_PIN 16528
#define XAUTH_ANSWER 16529
#define XAUTH_BASE XAUTH_TYPE
extern enum_names xauth_attr_names;
extern enum_names microsoft_attr_names;
/* ISAKMP mode config attributes specific to the Unity vendor ID */
#define UNITY_BANNER 28672
#define UNITY_SAVE_PASSWD 28673
#define UNITY_DEF_DOMAIN 28674
#define UNITY_SPLITDNS_NAME 28675
#define UNITY_SPLIT_INCLUDE 28676
#define UNITY_NATT_PORT 28677
#define UNITY_LOCAL_LAN 28678
#define UNITY_PFS 28679
#define UNITY_FW_TYPE 28680
#define UNITY_BACKUP_SERVERS 28681
#define UNITY_DDNS_HOSTNAME 28682
#define UNITY_BASE UNITY_BANNER
extern enum_names unity_attr_names;
/* XAUTH authentication types */
#define XAUTH_TYPE_GENERIC 0
#define XAUTH_TYPE_CHAP 1

View File

@ -702,7 +702,7 @@ void accept_delete(struct state *st, struct msg_digest *md,
struct payload_digest *p)
{
struct isakmp_delete *d = &(p->payload.delete);
identification_t *this_id, *that_id;
identification_t *this_id = NULL, *that_id = NULL;
ip_address peer_addr;
size_t sizespi;
int i;
@ -1949,19 +1949,18 @@ stf_status quick_outI1(int whack_sock, struct state *isakmp_sa,
u_int8_t np = ISAKMP_NEXT_NONE;
if (c->spd.this.modecfg && !c->spd.this.has_client &&
isanyaddr(&c->spd.this.host_srcip))
c->spd.this.host_srcip->is_anyaddr(c->spd.this.host_srcip))
{
connection_t *ph1_c = isakmp_sa->st_connection;
host_t * ph1_srcip = ph1_c->spd.this.host_srcip;
if (ph1_c->spd.this.modecfg && !isanyaddr(&ph1_c->spd.this.host_srcip))
if (ph1_c->spd.this.modecfg && !ph1_srcip->is_anyaddr(ph1_srcip))
{
char srcip[ADDRTOT_BUF];
c->spd.this.host_srcip = ph1_c->spd.this.host_srcip;
c->spd.this.host_srcip->destroy(c->spd.this.host_srcip);
c->spd.this.host_srcip = ph1_srcip->clone(ph1_srcip);
c->spd.this.client = ph1_c->spd.this.client;
c->spd.this.has_client = TRUE;
addrtot(&c->spd.this.host_srcip, 0, srcip, sizeof(srcip));
plog("inheriting virtual IP source address %s from ModeCfg", srcip);
plog("inheriting virtual IP source address %H from ModeCfg", ph1_srcip);
}
}
@ -4888,20 +4887,20 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b,
/* Plain Road Warrior:
* instantiate, carrying over authenticated peer ID
*/
host_t *vip = c->spd.that.host_srcip;
p = rw_instantiate(p, &c->spd.that.host_addr, md->sender_port
, his_net, c->spd.that.id);
/* inherit any virtual IP assigned by a Mode Config exchange */
if (p->spd.that.modecfg && c->spd.that.modecfg &&
subnetisaddr(his_net, &c->spd.that.host_srcip))
subnetisaddr(his_net, (ip_address*)vip->get_sockaddr(vip)))
{
char srcip[ADDRTOT_BUF];
DBG(DBG_CONTROL,
addrtot(&c->spd.that.host_srcip, 0, srcip, sizeof(srcip));
DBG_log("inheriting virtual IP source address %s from ModeCfg", srcip)
DBG_log("inheriting virtual IP source address %H from ModeCfg", vip)
)
p->spd.that.host_srcip = c->spd.that.host_srcip;
p->spd.that.host_srcip->destroy(p->spd.that.host_srcip);
p->spd.that.host_srcip = vip->clone(vip);
p->spd.that.client = c->spd.that.client;
p->spd.that.has_client = TRUE;
}

View File

@ -483,16 +483,14 @@ static bool do_command(connection_t *c, struct spd_route *sr,
strncat(nexthop_str, "' ", sizeof(nexthop_str));
}
if (addrbytesptr(&sr->this.host_srcip, NULL)
&& !isanyaddr(&sr->this.host_srcip))
if (!sr->this.host_srcip->is_anyaddr(sr->this.host_srcip))
{
char *n;
strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
n = srcip_str + strlen(srcip_str);
addrtot(&sr->this.host_srcip, 0
,n , sizeof(srcip_str)-strlen(srcip_str));
snprintf(n, sizeof(srcip_str)-strlen(srcip_str), "%H",
sr->this.host_srcip);
strncat(srcip_str, "' ", sizeof(srcip_str));
}

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,11 @@ struct modecfg_attribute_t {
*/
u_int16_t type;
/**
* Attribute is coded as TV
*/
bool is_tv;
/**
* Attribute value as chunk.
*/