summaryrefslogtreecommitdiff
path: root/server/XfrmController.cpp
diff options
context:
space:
mode:
authorNathan Harold <nharold@google.com>2018-01-09 16:42:57 -0800
committerNathan Harold <nharold@google.com>2018-01-16 11:18:47 -0800
commitda54f121d3ee5cb9094bdfd4fca46e9085a7d49b (patch)
tree66a6a6ad2e8a86fd05e96f1b05970da511a2223b /server/XfrmController.cpp
parentd7dd1d3af4ebac422303370301f1d98c9a84a8ae (diff)
downloadnetd-da54f121d3ee5cb9094bdfd4fca46e9085a7d49b.tar.gz
Make Transforms Unidirectional
Convert the IpSecTransform from being a bi-directional pair of SAs to a unidirectional single SA. This CL also removes the concept of "direction from SAs meaning that a IpSecTransform may now be applied to a socket in either direction. -Remove direction parameter from SAs and SPIs. -Convert to using source and destination rather than local and remote addresses. Bug: 71717213 Test: CTS - IpSecManagerTest Change-Id: I7150c2b03057e18a7d9d3edff302baf10e1ee729
Diffstat (limited to 'server/XfrmController.cpp')
-rw-r--r--server/XfrmController.cpp135
1 files changed, 52 insertions, 83 deletions
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 24ccee49..648c7c07 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -352,18 +352,18 @@ netdutils::Status XfrmController::ipSecSetEncapSocketOwner(const android::base::
if (info.st_uid != callerUid) {
return netdutils::statusFromErrno(EPERM, "fchown disabled for non-owner calls");
}
- if (S_ISSOCK(info.st_mode) == 0){
+ if (S_ISSOCK(info.st_mode) == 0) {
return netdutils::statusFromErrno(EINVAL, "File descriptor was not a socket");
}
int optval;
socklen_t optlen;
- netdutils::Status status = getSyscallInstance().getsockopt(Fd(socket), IPPROTO_UDP, UDP_ENCAP,
- &optval, &optlen);
+ netdutils::Status status =
+ getSyscallInstance().getsockopt(Fd(socket), IPPROTO_UDP, UDP_ENCAP, &optval, &optlen);
if (status != netdutils::status::ok) {
return status;
}
- if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE){
+ if (optval != UDP_ENCAP_ESPINUDP && optval != UDP_ENCAP_ESPINUDP_NON_IKE) {
return netdutils::statusFromErrno(EINVAL, "Socket did not have UDP-encap sockopt set");
}
if (fchown(fd, newUid, -1)) {
@@ -373,20 +373,19 @@ netdutils::Status XfrmController::ipSecSetEncapSocketOwner(const android::base::
return netdutils::status::ok;
}
-netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t direction,
- const std::string& localAddress,
- const std::string& remoteAddress, int32_t inSpi,
- int32_t* outSpi) {
+netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId,
+ const std::string& sourceAddress,
+ const std::string& destinationAddress,
+ int32_t inSpi, int32_t* outSpi) {
ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
- ALOGD("direction=%d", direction);
- ALOGD("localAddress=%s", localAddress.c_str());
- ALOGD("remoteAddress=%s", remoteAddress.c_str());
+ ALOGD("sourceAddress=%s", sourceAddress.c_str());
+ ALOGD("destinationAddress=%s", destinationAddress.c_str());
ALOGD("inSpi=%0.8x", inSpi);
XfrmSaInfo saInfo{};
netdutils::Status ret =
- fillXfrmId(direction, localAddress, remoteAddress, INVALID_SPI, transformId, &saInfo);
+ fillXfrmId(sourceAddress, destinationAddress, INVALID_SPI, transformId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -414,8 +413,8 @@ netdutils::Status XfrmController::ipSecAllocateSpi(int32_t transformId, int32_t
}
netdutils::Status XfrmController::ipSecAddSecurityAssociation(
- int32_t transformId, int32_t mode, int32_t direction, const std::string& localAddress,
- const std::string& remoteAddress, int64_t underlyingNetworkHandle, int32_t spi,
+ int32_t transformId, int32_t mode, const std::string& sourceAddress,
+ const std::string& destinationAddress, int64_t underlyingNetworkHandle, int32_t spi,
const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
const std::string& aeadAlgo, const std::vector<uint8_t>& aeadKey, int32_t aeadIcvBits,
@@ -423,9 +422,8 @@ netdutils::Status XfrmController::ipSecAddSecurityAssociation(
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("mode=%d", mode);
- ALOGD("direction=%d", direction);
- ALOGD("localAddress=%s", localAddress.c_str());
- ALOGD("remoteAddress=%s", remoteAddress.c_str());
+ ALOGD("sourceAddress=%s", sourceAddress.c_str());
+ ALOGD("destinationAddress=%s", destinationAddress.c_str());
ALOGD("underlyingNetworkHandle=%" PRIx64, underlyingNetworkHandle);
ALOGD("spi=%0.8x", spi);
ALOGD("authAlgo=%s", authAlgo.c_str());
@@ -440,7 +438,7 @@ netdutils::Status XfrmController::ipSecAddSecurityAssociation(
XfrmSaInfo saInfo{};
netdutils::Status ret =
- fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saInfo);
+ fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saInfo);
if (!isOk(ret)) {
return ret;
}
@@ -454,8 +452,6 @@ netdutils::Status XfrmController::ipSecAddSecurityAssociation(
saInfo.aead = XfrmAlgo{
.name = aeadAlgo, .key = aeadKey, .truncLenBits = static_cast<uint16_t>(aeadIcvBits)};
- saInfo.direction = static_cast<XfrmDirection>(direction);
-
switch (static_cast<XfrmMode>(mode)) {
case XfrmMode::TRANSPORT:
case XfrmMode::TUNNEL:
@@ -478,18 +474,10 @@ netdutils::Status XfrmController::ipSecAddSecurityAssociation(
if (saInfo.addrFamily != AF_INET) {
return netdutils::statusFromErrno(EAFNOSUPPORT, "IPv6 encap not supported");
}
- switch (saInfo.direction) {
- case XfrmDirection::IN:
- saInfo.encap.srcPort = encapRemotePort;
- saInfo.encap.dstPort = encapLocalPort;
- break;
- case XfrmDirection::OUT:
- saInfo.encap.srcPort = encapLocalPort;
- saInfo.encap.dstPort = encapRemotePort;
- break;
- default:
- return netdutils::statusFromErrno(EINVAL, "Invalid direction");
- }
+ // The ports are not used on input SAs, so this is OK to be wrong when
+ // direction is ultimately input.
+ saInfo.encap.srcPort = encapLocalPort;
+ saInfo.encap.dstPort = encapRemotePort;
// fall through
case XfrmEncapType::NONE:
saInfo.encap.type = static_cast<XfrmEncapType>(encapType);
@@ -506,21 +494,18 @@ netdutils::Status XfrmController::ipSecAddSecurityAssociation(
return ret;
}
-netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId,
- int32_t direction,
- const std::string& localAddress,
- const std::string& remoteAddress,
- int32_t spi) {
+netdutils::Status
+XfrmController::ipSecDeleteSecurityAssociation(int32_t transformId,
+ const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t spi) {
ALOGD("XfrmController:%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
- ALOGD("direction=%d", direction);
- ALOGD("localAddress=%s", localAddress.c_str());
- ALOGD("remoteAddress=%s", remoteAddress.c_str());
+ ALOGD("sourceAddress=%s", sourceAddress.c_str());
+ ALOGD("destinationAddress=%s", destinationAddress.c_str());
ALOGD("spi=%0.8x", spi);
XfrmId saId{};
- netdutils::Status ret =
- fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saId);
+ netdutils::Status ret = fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saId);
if (!isOk(ret)) {
return ret;
}
@@ -540,61 +525,45 @@ netdutils::Status XfrmController::ipSecDeleteSecurityAssociation(int32_t transfo
return ret;
}
-netdutils::Status XfrmController::fillXfrmId(int32_t direction, const std::string& localAddress,
- const std::string& remoteAddress, int32_t spi,
+netdutils::Status XfrmController::fillXfrmId(const std::string& sourceAddress,
+ const std::string& destinationAddress, int32_t spi,
int32_t transformId, XfrmId* xfrmId) {
// Fill the straightforward fields first
xfrmId->transformId = transformId;
- xfrmId->direction = static_cast<XfrmDirection>(direction);
xfrmId->spi = htonl(spi);
// Use the addresses to determine the address family and do validation
- xfrm_address_t localXfrmAddr{}, remoteXfrmAddr{};
- StatusOr<int> addrFamilyLocal, addrFamilyRemote;
- addrFamilyRemote = convertToXfrmAddr(remoteAddress, &remoteXfrmAddr);
- addrFamilyLocal = convertToXfrmAddr(localAddress, &localXfrmAddr);
- if (!isOk(addrFamilyRemote) || !isOk(addrFamilyLocal)) {
- return netdutils::statusFromErrno(EINVAL,
- "Invalid address " + localAddress + "/" + remoteAddress);
- }
-
- if (addrFamilyRemote.value() == AF_UNSPEC ||
- (addrFamilyLocal.value() != AF_UNSPEC &&
- addrFamilyLocal.value() != addrFamilyRemote.value())) {
- ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", addrFamilyLocal.value(),
- addrFamilyRemote.value(), __LINE__);
+ xfrm_address_t sourceXfrmAddr{}, destXfrmAddr{};
+ StatusOr<int> sourceFamily, destFamily;
+ sourceFamily = convertToXfrmAddr(sourceAddress, &sourceXfrmAddr);
+ destFamily = convertToXfrmAddr(destinationAddress, &destXfrmAddr);
+ if (!isOk(sourceFamily) || !isOk(destFamily)) {
+ return netdutils::statusFromErrno(EINVAL, "Invalid address " + sourceAddress + "/" +
+ destinationAddress);
+ }
+
+ if (destFamily.value() == AF_UNSPEC ||
+ (sourceFamily.value() != AF_UNSPEC && sourceFamily.value() != destFamily.value())) {
+ ALOGD("Invalid or Mismatched Address Families, %d != %d, line=%d", sourceFamily.value(),
+ destFamily.value(), __LINE__);
return netdutils::statusFromErrno(EINVAL, "Invalid or mismatched address families");
}
- xfrmId->addrFamily = addrFamilyRemote.value();
-
- switch (static_cast<XfrmDirection>(direction)) {
- case XfrmDirection::IN:
- xfrmId->dstAddr = localXfrmAddr;
- xfrmId->srcAddr = remoteXfrmAddr;
- break;
+ xfrmId->addrFamily = destFamily.value();
- case XfrmDirection::OUT:
- xfrmId->dstAddr = remoteXfrmAddr;
- xfrmId->srcAddr = localXfrmAddr;
- break;
-
- default:
- ALOGD("Invalid XFRM direction, line=%d", __LINE__);
- // Invalid direction for Transport mode transform: time to bail
- return netdutils::statusFromErrno(EINVAL, "Invalid direction");
- }
+ xfrmId->dstAddr = destXfrmAddr;
+ xfrmId->srcAddr = sourceXfrmAddr;
return netdutils::status::ok;
}
netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
const android::base::unique_fd& socket, int32_t transformId, int32_t direction,
- const std::string& localAddress, const std::string& remoteAddress, int32_t spi) {
+ const std::string& sourceAddress, const std::string& destinationAddress, int32_t spi) {
ALOGD("XfrmController::%s, line=%d", __FUNCTION__, __LINE__);
ALOGD("transformId=%d", transformId);
ALOGD("direction=%d", direction);
- ALOGD("localAddress=%s", localAddress.c_str());
- ALOGD("remoteAddress=%s", remoteAddress.c_str());
+ ALOGD("sourceAddress=%s", sourceAddress.c_str());
+ ALOGD("destinationAddress=%s", destinationAddress.c_str());
ALOGD("spi=%0.8x", spi);
StatusOr<sockaddr_storage> ret = getSyscallInstance().getsockname<sockaddr_storage>(Fd(socket));
@@ -606,7 +575,7 @@ netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
XfrmSaInfo saInfo{};
netdutils::Status status =
- fillXfrmId(direction, localAddress, remoteAddress, spi, transformId, &saInfo);
+ fillXfrmId(sourceAddress, destinationAddress, spi, transformId, &saInfo);
if (!isOk(status)) {
ALOGE("Couldn't build SA ID %s", __FUNCTION__);
return status;
@@ -624,7 +593,7 @@ netdutils::Status XfrmController::ipSecApplyTransportModeTransform(
xfrm_user_tmpl tmpl;
} policy{};
- fillTransportModeUserSpInfo(saInfo, &policy.info);
+ fillTransportModeUserSpInfo(saInfo, static_cast<XfrmDirection>(direction), &policy.info);
fillUserTemplate(saInfo, &policy.tmpl);
LOG_HEX("XfrmUserPolicy", reinterpret_cast<char*>(&policy), sizeof(policy));
@@ -900,7 +869,7 @@ netdutils::Status XfrmController::allocateSpi(const XfrmSaInfo& record, uint32_t
return ret;
}
-int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record,
+int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record, XfrmDirection direction,
xfrm_userpolicy_info* usersp) {
fillTransportModeSelector(record, &usersp->sel);
fillXfrmLifetimeDefaults(&usersp->lft);
@@ -908,7 +877,7 @@ int XfrmController::fillTransportModeUserSpInfo(const XfrmSaInfo& record,
/* if (index) index & 0x3 == dir -- must be true
* xfrm_user.c:verify_newpolicy_info() */
usersp->index = 0;
- usersp->dir = static_cast<uint8_t>(record.direction);
+ usersp->dir = static_cast<uint8_t>(direction);
usersp->action = XFRM_POLICY_ALLOW;
usersp->flags = XFRM_POLICY_LOCALOK;
usersp->share = XFRM_SHARE_UNIQUE;