Skip to content

Commit

Permalink
Merge pull request #225 from microsoft/apcontrolciphers
Browse files Browse the repository at this point in the history
Change list of cipher suites in configuration api structure to map of security protocols -> cipher suites
  • Loading branch information
abeltrano authored Mar 15, 2024
2 parents dbf5a1e + 377446c commit b470190
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 8 deletions.
8 changes: 7 additions & 1 deletion protocol/protos/WifiCore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,18 @@ message Dot11SharedKey
}
}

message Dot11CipherSuiteConfiguration
{
Dot11SecurityProtocol SecurityProtocol = 1;
repeated Dot11CipherSuite CipherSuites = 2;
}

message Dot11AccessPointConfiguration
{
Dot11Ssid Ssid = 1;
Dot11MacAddress Bssid = 2;
Dot11PhyType PhyType = 3;
Dot11CipherSuite CipherSuite = 4;
repeated Dot11CipherSuiteConfiguration CipherSuites = 4;
repeated Dot11AuthenticationAlgorithm AuthenticationAlgorithms = 5;
repeated Dot11FrequencyBand FrequencyBands = 6;
}
Expand Down
60 changes: 58 additions & 2 deletions src/common/service/NetRemoteService.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <format>
#include <iterator>
#include <memory>
#include <ranges>
#include <string>
#include <string_view>
#include <utility>
Expand Down Expand Up @@ -461,8 +462,12 @@ NetRemoteService::WifiAccessPointEnableImpl(std::string_view accessPointId, cons
}
}

if (dot11AccessPointConfiguration->ciphersuite() != Dot11CipherSuite::Dot11CipherSuiteUnknown) {
// TODO: set cipher suite.
if (dot11AccessPointConfiguration->ciphersuites_size() > 0) {
auto dot11CipherSuites = ToDot11CipherSuiteConfigurations(dot11AccessPointConfiguration->ciphersuites());
wifiOperationStatus = WifiAccessPointSetCipherSuitesImpl(accessPointId, dot11CipherSuites, accessPointController);
if (wifiOperationStatus.code() != WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded) {
return wifiOperationStatus;
}
}

if (dot11AccessPointConfiguration->has_ssid()) {
Expand Down Expand Up @@ -680,6 +685,57 @@ NetRemoteService::WifiAccessPointSetAuthenticationAlgorithsmImpl(std::string_vie
return wifiOperationStatus;
}

WifiAccessPointOperationStatus
NetRemoteService::WifiAccessPointSetCipherSuitesImpl(std::string_view accessPointId, std::unordered_map<Dot11SecurityProtocol, std::vector<Dot11CipherSuite>>& dot11CipherSuites, std::shared_ptr<IAccessPointController> accessPointController)
{
WifiAccessPointOperationStatus wifiOperationStatus{};

// Validate basic parameters in the request.
if (std::empty(dot11CipherSuites)) {
wifiOperationStatus.set_code(WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInvalidParameter);
wifiOperationStatus.set_message("No cipher suites provided");
return wifiOperationStatus;
}
if (std::ranges::contains(dot11CipherSuites | std::views::keys, Dot11SecurityProtocol::Dot11SecurityProtocolUnknown)) {
wifiOperationStatus.set_code(WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInvalidParameter);
wifiOperationStatus.set_message("Invalid security protocol provided");
return wifiOperationStatus;
}

AccessPointOperationStatus operationStatus{ accessPointId };

// Create an AP controller for the requested AP if one wasn't specified.
if (accessPointController == nullptr) {
operationStatus = TryGetAccessPointController(accessPointId, accessPointController);
if (!operationStatus.Succeeded() || accessPointController == nullptr) {
wifiOperationStatus.set_code(ToDot11AccessPointOperationStatusCode(operationStatus.Code));
wifiOperationStatus.set_message(std::format("Failed to create access point controller for access point {} - {}", accessPointId, operationStatus.ToString()));
return wifiOperationStatus;
}
}

// Convert to 802.11 neutral type.
auto ieee80211CipherSuites = FromDot11CipherSuiteConfigurations(dot11CipherSuites);
if (std::ranges::contains(ieee80211CipherSuites | std::views::keys, Ieee80211SecurityProtocol::Unknown)) {
wifiOperationStatus.set_code(WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeInvalidParameter);
wifiOperationStatus.set_message("Invalid security protocol provided");
return wifiOperationStatus;
}

// Set the cipher suites.
operationStatus.Code = AccessPointOperationStatusCode::OperationNotSupported;
// TODO: operationStatus = accessPointController->SetCipherSuites(std::move(ieee80211CipherSuites));
if (!operationStatus.Succeeded()) {
wifiOperationStatus.set_code(ToDot11AccessPointOperationStatusCode(operationStatus.Code));
wifiOperationStatus.set_message(std::format("Failed to set cipher suites for access point {} - {}", accessPointId, operationStatus.ToString()));
return wifiOperationStatus;
}

wifiOperationStatus.set_code(WifiAccessPointOperationStatusCode::WifiAccessPointOperationStatusCodeSucceeded);

return wifiOperationStatus;
}

WifiAccessPointOperationStatus
NetRemoteService::WifiAccessPointSetSsidImpl(std::string_view accessPointId, const Dot11Ssid& dot11Ssid, std::shared_ptr<IAccessPointController> accessPointController)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ protected:
Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
WifiAccessPointSetAuthenticationAlgorithsmImpl(std::string_view accessPointId, std::vector<Microsoft::Net::Wifi::Dot11AuthenticationAlgorithm>& dot11AuthenticationAlgorithms, std::shared_ptr<Microsoft::Net::Wifi::IAccessPointController> accessPointController = nullptr);

/**
* @brief Set the active cipher suites of the access point. If the access point is online, this will cause it to
* temporarily go offline while the change is being applied.
*
* @param accessPointId The access point identifier.
* @param dot11CipherSuites The new cipher suites to set.
* @param accessPointController The access point controller for the specified access point (optional).
* @return Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
*/
Microsoft::Net::Remote::Wifi::WifiAccessPointOperationStatus
WifiAccessPointSetCipherSuitesImpl(std::string_view accessPointId, std::unordered_map<Microsoft::Net::Wifi::Dot11SecurityProtocol, std::vector<Microsoft::Net::Wifi::Dot11CipherSuite>>& dot11CipherSuites, std::shared_ptr<Microsoft::Net::Wifi::IAccessPointController> accessPointController = nullptr);

/**
* @brief Set the SSID of the access point.
*
Expand Down
36 changes: 36 additions & 0 deletions src/common/wifi/dot11/adapter/Ieee80211Dot11Adapters.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cstddef>
#include <iterator>
#include <ranges>
#include <unordered_map>
#include <vector>

#include <microsoft/net/remote/protocol/NetRemoteWifi.pb.h>
Expand Down Expand Up @@ -210,6 +211,13 @@ constexpr auto toDot11AuthenticationAlgorithm = [](const auto& authenticationAlg
constexpr auto toDot11FrequencyBand = [](const auto& frequencyBand) {
return static_cast<Dot11FrequencyBand>(frequencyBand);
};

/**
* @brief Convert an int-typed Dot11CipherSuite to its proper enum type.
*/
constexpr auto toDot11CipherSuite = [](const auto& cipherSuite) {
return static_cast<Dot11CipherSuite>(cipherSuite);
};
} // namespace detail

std::vector<Dot11AuthenticationAlgorithm>
Expand Down Expand Up @@ -484,6 +492,34 @@ FromDot11CipherSuite(const Dot11CipherSuite dot11CipherSuite) noexcept
}
}

std::unordered_map<Dot11SecurityProtocol, std::vector<Dot11CipherSuite>>
ToDot11CipherSuiteConfigurations(const google::protobuf::RepeatedPtrField<Dot11CipherSuiteConfiguration>& dot11CipherSuiteConfigurations) noexcept
{
std::unordered_map<Dot11SecurityProtocol, std::vector<Dot11CipherSuite>> dot11CipherSuiteConfigurationsStrong{};

for (const auto& dot11CipherSuiteConfiguration : dot11CipherSuiteConfigurations) {
std::vector<Dot11CipherSuite> dot11CipherSuites(static_cast<std::size_t>(dot11CipherSuiteConfiguration.ciphersuites_size()));
std::ranges::transform(dot11CipherSuiteConfiguration.ciphersuites(), std::begin(dot11CipherSuites), detail::toDot11CipherSuite);
dot11CipherSuiteConfigurationsStrong.emplace(dot11CipherSuiteConfiguration.securityprotocol(), std::move(dot11CipherSuites));
}

return dot11CipherSuiteConfigurationsStrong;
}

std::unordered_map<Ieee80211SecurityProtocol, std::vector<Ieee80211CipherSuite>>
FromDot11CipherSuiteConfigurations(const std::unordered_map<Dot11SecurityProtocol, std::vector<Dot11CipherSuite>>& dot11CipherSuiteConfigurations) noexcept
{
std::unordered_map<Ieee80211SecurityProtocol, std::vector<Ieee80211CipherSuite>> ieee80211CipherSuiteConfigurations{};

for (const auto& [dot11SecurityProtocol, dot11CipherSuites] : dot11CipherSuiteConfigurations) {
std::vector<Ieee80211CipherSuite> ieee80211CipherSuites(std::size(dot11CipherSuites));
std::ranges::transform(dot11CipherSuites, std::begin(ieee80211CipherSuites), FromDot11CipherSuite);
ieee80211CipherSuiteConfigurations.emplace(FromDot11SecurityProtocol(dot11SecurityProtocol), std::move(ieee80211CipherSuites));
}

return ieee80211CipherSuiteConfigurations;
}

using Microsoft::Net::Wifi::Dot11AccessPointCapabilities;
using Microsoft::Net::Wifi::Ieee80211AccessPointCapabilities;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#ifndef IEEE_80211_DOT11_ADAPTERS_HXX
#define IEEE_80211_DOT11_ADAPTERS_HXX

#include <unordered_map>
#include <vector>

#include <microsoft/net/remote/protocol/NetRemoteWifi.pb.h>
Expand Down Expand Up @@ -175,6 +176,24 @@ ToDot11CipherSuite(Microsoft::Net::Wifi::Ieee80211CipherSuite ieee80211CipherSui
Microsoft::Net::Wifi::Ieee80211CipherSuite
FromDot11CipherSuite(Microsoft::Net::Wifi::Dot11CipherSuite dot11CipherSuite) noexcept;

/**
* @brief Convert the specified repeated field of Dot11CipherSuiteConfigurations to the equivalent map of Dot11SecurityProtocol to Dot11CipherSuite.
*
* @param dot11CipherSuiteConfigurations The repeated field of Dot11CipherSuiteConfigurations to convert.
* @return std::unordered_map<Microsoft::Net::Wifi::Dot11SecurityProtocol, std::vector<Microsoft::Net::Wifi::Dot11CipherSuite>>
*/
std::unordered_map<Microsoft::Net::Wifi::Dot11SecurityProtocol, std::vector<Microsoft::Net::Wifi::Dot11CipherSuite>>
ToDot11CipherSuiteConfigurations(const google::protobuf::RepeatedPtrField<Microsoft::Net::Wifi::Dot11CipherSuiteConfiguration>& dot11CipherSuiteConfigurations) noexcept;

/**
* @brief Convert the specified map of Dot11SecurityProtocol to Dot11CipherSuite to the equivalent map of IEEE 802.11 security protocol to cipher suite.
*
* @param dot11CipherSuiteConfigurations The map of Dot11SecurityProtocol to Dot11CipherSuite to convert.
* @return std::unordered_map<Microsoft::Net::Wifi::Ieee80211SecurityProtocol, std::vector<Microsoft::Net::Wifi::Ieee80211CipherSuite>>
*/
std::unordered_map<Microsoft::Net::Wifi::Ieee80211SecurityProtocol, std::vector<Microsoft::Net::Wifi::Ieee80211CipherSuite>>
FromDot11CipherSuiteConfigurations(const std::unordered_map<Microsoft::Net::Wifi::Dot11SecurityProtocol, std::vector<Microsoft::Net::Wifi::Dot11CipherSuite>>& dot11CipherSuiteConfigurations) noexcept;

/**
* @brief Convert the specified IEEE 802.11 access point capabilities to the equivalent Dot11AccessPointCapabilities.
*
Expand Down
18 changes: 13 additions & 5 deletions tests/unit/TestNetRemoteServiceClient.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,14 @@ TEST_CASE("WifiAccessPointEnable API", "[basic][rpc][client][remote]")

SECTION("Can be called")
{
Dot11CipherSuiteConfiguration dot11CipherSuiteConfigurationWpa1{};
dot11CipherSuiteConfigurationWpa1.set_securityprotocol(Dot11SecurityProtocol::Dot11SecurityProtocolWpa);
dot11CipherSuiteConfigurationWpa1.mutable_ciphersuites()->Add(Dot11CipherSuite::Dot11CipherSuiteCcmp256);

Dot11AccessPointConfiguration apConfiguration{};
apConfiguration.mutable_ssid()->set_name(SsidName);
apConfiguration.set_phytype(Dot11PhyType::Dot11PhyTypeA);
apConfiguration.set_ciphersuite(Dot11CipherSuite::Dot11CipherSuiteCcmp256);
apConfiguration.mutable_ssid()->set_name(SsidName);
apConfiguration.mutable_ciphersuites()->Add(std::move(dot11CipherSuiteConfigurationWpa1));
apConfiguration.mutable_authenticationalgorithms()->Add(Dot11AuthenticationAlgorithm::Dot11AuthenticationAlgorithmSharedKey);
apConfiguration.mutable_frequencybands()->Add(Dot11FrequencyBand::Dot11FrequencyBand2_4GHz);
apConfiguration.mutable_frequencybands()->Add(Dot11FrequencyBand::Dot11FrequencyBand5_0GHz);
Expand All @@ -147,7 +151,7 @@ TEST_CASE("WifiAccessPointEnable API", "[basic][rpc][client][remote]")
SECTION("Fails with invalid access point")
{
WifiAccessPointEnableRequest request{};
*request.mutable_configuration() = {};
*request.mutable_configuration() = {};
request.set_accesspointid(InterfaceNameInvalid);

WifiAccessPointEnableResult result{};
Expand All @@ -163,11 +167,15 @@ TEST_CASE("WifiAccessPointEnable API", "[basic][rpc][client][remote]")

SECTION("Succeeds without access point configuration if already configured")
{
Dot11CipherSuiteConfiguration dot11CipherSuiteConfigurationWpa1{};
dot11CipherSuiteConfigurationWpa1.set_securityprotocol(Dot11SecurityProtocol::Dot11SecurityProtocolWpa);
dot11CipherSuiteConfigurationWpa1.mutable_ciphersuites()->Add(Dot11CipherSuite::Dot11CipherSuiteCcmp256);

// Perform initial enable with configuration.
Dot11AccessPointConfiguration apConfiguration{};
apConfiguration.mutable_ssid()->set_name(SsidName);
apConfiguration.set_phytype(Dot11PhyType::Dot11PhyTypeA);
apConfiguration.set_ciphersuite(Dot11CipherSuite::Dot11CipherSuiteCcmp256);
apConfiguration.mutable_ssid()->set_name(SsidName);
apConfiguration.mutable_ciphersuites()->Add(std::move(dot11CipherSuiteConfigurationWpa1));
apConfiguration.mutable_authenticationalgorithms()->Add(Dot11AuthenticationAlgorithm::Dot11AuthenticationAlgorithmSharedKey);
apConfiguration.mutable_frequencybands()->Add(Dot11FrequencyBand::Dot11FrequencyBand2_4GHz);

Expand Down

0 comments on commit b470190

Please sign in to comment.