kernel-wfp: Implement update_sa()
This commit is contained in:
@@ -90,3 +90,9 @@ STUB(fwpuclnt, DWORD, IPsecSaContextCreate1, 40,
|
||||
|
||||
STUB(fwpuclnt, DWORD, IPsecSaContextSetSpi0, 32,
|
||||
HANDLE engineHandle, UINT64 id, const void *getSpi, UINT32 inboundSpi)
|
||||
|
||||
STUB(fwpuclnt, DWORD, IPsecSaContextGetById1, 24,
|
||||
HANDLE engineHandle, UINT64 id, void **saContext)
|
||||
|
||||
STUB(fwpuclnt, DWORD, IPsecSaContextUpdate0, 24,
|
||||
HANDLE engineHandle, UINT32 flags, const void *newValues)
|
||||
|
||||
@@ -51,6 +51,17 @@ enum {
|
||||
FWPM_TUNNEL_FLAG_ENABLE_VIRTUAL_IF_TUNNELING = (1<<1),
|
||||
};
|
||||
|
||||
/* missing in MinGW */
|
||||
enum {
|
||||
IPSEC_SA_DETAILS_UPDATE_TRAFFIC = (1<<0),
|
||||
IPSEC_SA_DETAILS_UPDATE_UDP_ENCAPSULATION = (1<<1),
|
||||
IPSEC_SA_BUNDLE_UPDATE_FLAGS = (1<<2),
|
||||
IPSEC_SA_BUNDLE_UPDATE_NAP_CONTEXT = (1<<3),
|
||||
IPSEC_SA_BUNDLE_UPDATE_KEY_MODULE_STATE = (1<<4),
|
||||
IPSEC_SA_BUNDLE_UPDATE_PEER_V4_PRIVATE_ADDRESS = (1<<5),
|
||||
IPSEC_SA_BUNDLE_UPDATE_MM_SA_ID = (1<<6),
|
||||
};
|
||||
|
||||
DWORD WINAPI FwpmIPsecTunnelAdd0(HANDLE, UINT32,
|
||||
const FWPM_PROVIDER_CONTEXT0*, const FWPM_PROVIDER_CONTEXT0*, UINT32,
|
||||
const FWPM_FILTER_CONDITION0*, PSECURITY_DESCRIPTOR);
|
||||
|
||||
@@ -1509,7 +1509,103 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap, mark_t mark)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
entry_t *entry;
|
||||
sa_entry_t key = {
|
||||
.dst = dst,
|
||||
.spi = spi,
|
||||
};
|
||||
UINT64 sa_id = 0;
|
||||
IPSEC_SA_CONTEXT1 *ctx;
|
||||
IPSEC_V4_UDP_ENCAPSULATION0 ports;
|
||||
UINT32 flags = IPSEC_SA_DETAILS_UPDATE_TRAFFIC;
|
||||
DWORD res;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
entry = this->osas->get(this->osas, &key);
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
/* outbound entry, nothing to do */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
entry = this->isas->get(this->isas, &key);
|
||||
if (entry)
|
||||
{
|
||||
/* inbound entry, do update */
|
||||
sa_id = entry->sa_id;
|
||||
ports.localUdpEncapPort = entry->local->get_port(entry->local);
|
||||
ports.remoteUdpEncapPort = entry->remote->get_port(entry->remote);
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
if (!sa_id)
|
||||
{
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
res = IPsecSaContextGetById1(this->handle, sa_id, &ctx);
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "getting WFP SA context for updated failed: 0x%08x", res);
|
||||
return FAILED;
|
||||
}
|
||||
if (!hosts2traffic(this, new_dst, new_src, &ctx->inboundSa->traffic) ||
|
||||
!hosts2traffic(this, new_dst, new_src, &ctx->outboundSa->traffic))
|
||||
{
|
||||
FwpmFreeMemory0((void**)&ctx);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (new_encap != encap)
|
||||
{
|
||||
if (new_encap)
|
||||
{
|
||||
ctx->inboundSa->udpEncapsulation = &ports;
|
||||
ctx->outboundSa->udpEncapsulation = &ports;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->inboundSa->udpEncapsulation = NULL;
|
||||
ctx->outboundSa->udpEncapsulation = NULL;
|
||||
}
|
||||
flags |= IPSEC_SA_DETAILS_UPDATE_UDP_ENCAPSULATION;
|
||||
}
|
||||
|
||||
res = IPsecSaContextUpdate0(this->handle, flags, ctx);
|
||||
FwpmFreeMemory0((void**)&ctx);
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "updating WFP SA context failed: 0x%08x", res);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
entry = this->isas->remove(this->isas, &key);
|
||||
if (entry)
|
||||
{
|
||||
key.spi = entry->osa.spi;
|
||||
key.dst = entry->osa.dst;
|
||||
this->osas->remove(this->osas, &key);
|
||||
|
||||
entry->local->destroy(entry->local);
|
||||
entry->remote->destroy(entry->remote);
|
||||
entry->local = new_dst->clone(new_dst);
|
||||
entry->remote = new_src->clone(new_src);
|
||||
entry->isa.dst = entry->local;
|
||||
entry->osa.dst = entry->remote;
|
||||
|
||||
this->isas->put(this->isas, &entry->isa, entry);
|
||||
this->osas->put(this->osas, &entry->osa, entry);
|
||||
|
||||
manage_routes(this, entry, FALSE);
|
||||
manage_routes(this, entry, TRUE);
|
||||
}
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||
|
||||
Reference in New Issue
Block a user