pluto: Migrated get_ipsec_spi to libhydra's kernel interface.

This commit is contained in:
Tobias Brunner
2010-09-02 19:04:19 +02:00
parent 55be07a15f
commit 89f0cca111
+20 -46
View File
@@ -1,7 +1,11 @@
/* routines that interface with the kernel's IPsec mechanism
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
* Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* Copyright (C) 2010 Tobias Brunner
* Copyright (C) 2009 Andreas Steffen
* Hochschule fuer Technik Rapperswil
*
* Copyright (C) 1998-2002 D. Hugh Redelmeier
* Copyright (C) 1997 Angelos D. Keromytis
*
* 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
@@ -32,6 +36,7 @@
#include <freeswan.h>
#include <library.h>
#include <hydra.h>
#include <crypto/rngs/rng.h>
#ifdef KLIPS
@@ -256,58 +261,27 @@ static unsigned get_proto_reqid(unsigned base, int proto)
/* Generate Unique SPI numbers.
*
* The specs say that the number must not be less than IPSEC_DOI_SPI_MIN.
* Pluto generates numbers not less than IPSEC_DOI_SPI_OUR_MIN,
* reserving numbers in between for manual keying (but we cannot so
* restrict numbers generated by our peer).
* XXX This should be replaced by a call to the kernel when
* XXX we get an API.
* The returned SPI is in network byte order.
* We use a random number as the initial SPI so that there is
* a good chance that different Pluto instances will choose
* different SPIs. This is good for two reasons.
* - the keying material for the initiator and responder only
* differs if the SPIs differ.
* - if Pluto is restarted, it would otherwise recycle the SPI
* numbers and confuse everything. When the kernel generates
* SPIs, this will no longer matter.
* We then allocate numbers sequentially. Thus we don't have to
* check if the number was previously used (assuming that no
* SPI lives longer than 4G of its successors).
*/
ipsec_spi_t get_ipsec_spi(ipsec_spi_t avoid, int proto, struct spd_route *sr,
bool tunnel)
{
static ipsec_spi_t spi = 0; /* host order, so not returned directly! */
char text_said[SATOT_BUF];
rng_t *rng;
host_t *host_src, *host_dst;
u_int32_t spi;
set_text_said(text_said, &sr->this.host_addr, 0, proto);
host_src = host_create_from_sockaddr((sockaddr_t*)&sr->that.host_addr);
host_dst = host_create_from_sockaddr((sockaddr_t*)&sr->this.host_addr);
if (kernel_ops->get_spi)
if (hydra->kernel_interface->get_spi(hydra->kernel_interface, host_src,
host_dst, proto, sr->reqid, &spi) != SUCCESS)
{
return kernel_ops->get_spi(&sr->that.host_addr
, &sr->this.host_addr, proto, tunnel
, get_proto_reqid(sr->reqid, proto)
, IPSEC_DOI_SPI_OUR_MIN, 0xffffffff
, text_said);
spi = 0;
}
spi++;
rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
while (spi < IPSEC_DOI_SPI_OUR_MIN || spi == ntohl(avoid))
{
rng->get_bytes(rng, sizeof(spi), (u_char *)&spi);
}
rng->destroy(rng);
DBG(DBG_CONTROL,
{
ipsec_spi_t spi_net = htonl(spi);
host_src->destroy(host_src);
host_dst->destroy(host_dst);
DBG_dump("generate SPI:", (u_char *)&spi_net, sizeof(spi_net));
});
return htonl(spi);
return spi;
}
/* Generate Unique CPI numbers.
@@ -491,7 +465,7 @@ static bool do_command(connection_t *c, struct spd_route *sr,
strcpy(srcip_str, "PLUTO_MY_SOURCEIP='");
n = srcip_str + strlen(srcip_str);
snprintf(n, sizeof(srcip_str)-strlen(srcip_str), "%H",
snprintf(n, sizeof(srcip_str)-strlen(srcip_str), "%H",
sr->this.host_srcip);
strncat(srcip_str, "' ", sizeof(srcip_str));
}
@@ -536,7 +510,7 @@ static bool do_command(connection_t *c, struct spd_route *sr,
{
if (key->issuer)
{
snprintf(peerca_str, BUF_LEN, "%Y", key->issuer);
snprintf(peerca_str, BUF_LEN, "%Y", key->issuer);
escape_metachar(peerca_str, secure_peerca_str, BUF_LEN);
}
else