Skip to content

Commit

Permalink
Merge pull request #126 from microsoft/capsakms
Browse files Browse the repository at this point in the history
Populate AKMs in capabilities portion of WifiEnumerateAccessPoints
  • Loading branch information
abeltrano authored Jan 24, 2024
2 parents 1cfac50 + 77eb5d4 commit 9d3de96
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 27 deletions.
2 changes: 1 addition & 1 deletion protocol/protos/WifiCore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ message Dot11AccessPointCapabilities
{
repeated Microsoft.Net.Wifi.Dot11FrequencyBand Bands = 1;
repeated Microsoft.Net.Wifi.Dot11PhyType PhyTypes = 2;
repeated Microsoft.Net.Wifi.Dot11AuthenticationAlgorithm AuthenticationAlgorithms = 3;
repeated Microsoft.Net.Wifi.Dot11AkmSuite AkmSuites = 3;
repeated Microsoft.Net.Wifi.Dot11CipherSuite CipherSuites = 4;
}

Expand Down
12 changes: 6 additions & 6 deletions src/common/service/NetRemoteService.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Ieee80211AkmSuiteToNetRemoteAkm(Ieee80211AkmSuite akmSuite)
return Dot11AkmSuite::Dot11AkmSuiteFt8021xSha384;
case Ieee80211AkmSuite::FilsSha256:
return Dot11AkmSuite::Dot11AkmSuiteFilsSha256;
case Ieee80211AkmSuite::FilsSha284:
case Ieee80211AkmSuite::FilsSha384:
return Dot11AkmSuite::Dot11AkmSuiteFilsSha384;
case Ieee80211AkmSuite::FtFilsSha256:
return Dot11AkmSuite::Dot11AkmSuiteFtFilsSha256;
Expand Down Expand Up @@ -226,12 +226,12 @@ IeeeAccessPointCapabilitiesToNetRemoteAccessPointCapabilities(const Microsoft::N
std::make_move_iterator(std::end(bands))
};

std::vector<Microsoft::Net::Wifi::Dot11AuthenticationAlgorithm> authenticationAlgorithms(std::size(ieeeCapabilities.AuthenticationAlgorithms));
std::ranges::transform(ieeeCapabilities.AuthenticationAlgorithms, std::begin(authenticationAlgorithms), IeeeAuthenticationAlgorithmToNetRemoteAuthenticationAlgorithm);
std::vector<Microsoft::Net::Wifi::Dot11AkmSuite> akmSuites(std::size(ieeeCapabilities.AkmSuites));
std::ranges::transform(ieeeCapabilities.AkmSuites, std::begin(akmSuites), Ieee80211AkmSuiteToNetRemoteAkm);

*capabilities.mutable_authenticationalgorithms() = {
std::make_move_iterator(std::begin(authenticationAlgorithms)),
std::make_move_iterator(std::end(authenticationAlgorithms))
*capabilities.mutable_akmsuites() = {
std::make_move_iterator(std::begin(akmSuites)),
std::make_move_iterator(std::end(akmSuites))
};

std::vector<Microsoft::Net::Wifi::Dot11CipherSuite> cipherSuites(std::size(ieeeCapabilities.CipherSuites));
Expand Down
12 changes: 6 additions & 6 deletions src/common/tools/cli/NetRemoteCliHandlerOperations.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include <microsoft/net/remote/protocol/NetRemoteService.grpc.pb.h>
#include <plog/Log.h>

using namespace Microsoft::Net::Remote;

using namespace Microsoft::Net::Remote;
using namespace Microsoft::Net::Remote::Service;
using namespace Microsoft::Net::Remote::Wifi;
Expand Down Expand Up @@ -60,13 +58,15 @@ NetRemoteAccessPointCapabilitiesToString(const Microsoft::Net::Wifi::Dot11Access
<< indent1 << bandName;
}

constexpr auto AkmSuitePrefixLength = std::size(std::string_view("Dot11AkmSuite"));
ss << '\n'
<< indent0
<< "Authentication Algorithms:";
for (const auto& authenticationAlgorithm : accessPointCapabilities.authenticationalgorithms()) {
<< "Authentication and Key Management (AKM) Suites:";
for (const auto& akmSuite : accessPointCapabilities.akmsuites()) {
std::string_view akmSuiteName(magic_enum::enum_name(static_cast<Microsoft::Net::Wifi::Dot11AkmSuite>(akmSuite)));
akmSuiteName.remove_prefix(AkmSuitePrefixLength);
ss << '\n'
<< indent1
<< magic_enum::enum_name(static_cast<Microsoft::Net::Wifi::Dot11AuthenticationAlgorithm>(authenticationAlgorithm));
<< indent1 << akmSuiteName;
}

constexpr auto CipherAlgorithmPrefixLength = std::size(std::string_view("Dot11CipherSuite"));
Expand Down
5 changes: 5 additions & 0 deletions src/common/wifi/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ target_sources(wifi-core
${WIFI_CORE_PUBLIC_INCLUDE_PREFIX}/Ieee80211AccessPointCapabilities.hxx
)

target_link_libraries(wifi-core
PUBLIC
notstd
)

install(
TARGETS wifi-core
EXPORT ${PROJECT_NAME}
Expand Down
33 changes: 32 additions & 1 deletion src/common/wifi/core/include/microsoft/net/wifi/Ieee80211.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include <cmath>
#include <cstdint>
#include <initializer_list>

#include <notstd/Utility.hxx>

namespace Microsoft::Net::Wifi
{
Expand Down Expand Up @@ -187,14 +190,42 @@ enum class Ieee80211AkmSuite : uint32_t {
Ieee8011xSuiteB192 = MakeIeee80211Suite(Ieee80211AkmSuiteId8021xSuiteB192),
Ft8021xSha384 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFt8021xSha384),
FilsSha256 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFilsSha256),
FilsSha284 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFilsSha384),
FilsSha384 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFilsSha384),
FtFilsSha256 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFtFilsSha256),
FtFilsSha384 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFtFilsSha384),
Owe = MakeIeee80211Suite(Ieee80211AkmSuiteIdOwe),
FtPskSha384 = MakeIeee80211Suite(Ieee80211AkmSuiteIdFtPskSha384),
PskSha384 = MakeIeee80211Suite(Ieee80211AkmSuiteIdPskSha384),
};

/**
* @brief A listing of all known AKMs. Normally, these would be enumerated with magic_enum::enum_values(), however, that
* only supports enums with values up to UINT16_MAX-1, and the AKM suite underlying type is uint32_t, so cannot be used.
*/
constexpr std::initializer_list<uint32_t> AllIeee80211Akms{
notstd::to_underlying(Ieee80211AkmSuite::Reserved0),
notstd::to_underlying(Ieee80211AkmSuite::Ieee8021x),
notstd::to_underlying(Ieee80211AkmSuite::Psk),
notstd::to_underlying(Ieee80211AkmSuite::Ft8021x),
notstd::to_underlying(Ieee80211AkmSuite::FtPsk),
notstd::to_underlying(Ieee80211AkmSuite::Ieee8021xSha256),
notstd::to_underlying(Ieee80211AkmSuite::PskSha256),
notstd::to_underlying(Ieee80211AkmSuite::Tdls),
notstd::to_underlying(Ieee80211AkmSuite::Sae),
notstd::to_underlying(Ieee80211AkmSuite::FtSae),
notstd::to_underlying(Ieee80211AkmSuite::ApPeerKey),
notstd::to_underlying(Ieee80211AkmSuite::Ieee8021xSuiteB),
notstd::to_underlying(Ieee80211AkmSuite::Ieee8011xSuiteB192),
notstd::to_underlying(Ieee80211AkmSuite::Ft8021xSha384),
notstd::to_underlying(Ieee80211AkmSuite::FilsSha256),
notstd::to_underlying(Ieee80211AkmSuite::FilsSha384),
notstd::to_underlying(Ieee80211AkmSuite::FtFilsSha256),
notstd::to_underlying(Ieee80211AkmSuite::FtFilsSha384),
notstd::to_underlying(Ieee80211AkmSuite::Owe),
notstd::to_underlying(Ieee80211AkmSuite::FtPskSha384),
notstd::to_underlying(Ieee80211AkmSuite::PskSha384),
};

/**
* @brief Cipher suite identifiers or "selectors".
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct Ieee80211AccessPointCapabilities
{
std::vector<Ieee80211Protocol> Protocols;
std::vector<Ieee80211FrequencyBand> FrequencyBands;
std::vector<Ieee80211AuthenticationAlgorithm> AuthenticationAlgorithms;
std::vector<Ieee80211AkmSuite> AkmSuites;
std::vector<Ieee80211CipherSuite> CipherSuites;
};
} // namespace Microsoft::Net::Wifi
Expand Down
1 change: 1 addition & 0 deletions src/linux/libnl-helpers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ target_link_libraries(libnl-helpers
PRIVATE
magic_enum::magic_enum
plog::plog
wifi-core
PUBLIC
nl
nl-genl
Expand Down
32 changes: 26 additions & 6 deletions src/linux/libnl-helpers/Netlink80211Wiphy.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
#include <microsoft/net/netlink/nl80211/Netlink80211.hxx>
#include <microsoft/net/netlink/nl80211/Netlink80211ProtocolState.hxx>
#include <microsoft/net/netlink/nl80211/Netlink80211Wiphy.hxx>
#include <microsoft/net/wifi/Ieee80211.hxx>
#include <net/if.h>
#include <netlink/attr.h>
#include <netlink/genl/genl.h>
#include <plog/Log.h>

using namespace Microsoft::Net::Netlink::Nl80211;

Nl80211Wiphy::Nl80211Wiphy(uint32_t index, std::string_view name, std::vector<uint32_t> cipherSuites, std::unordered_map<nl80211_band, Nl80211WiphyBand> bands, std::vector<nl80211_iftype> supportedInterfaceTypes, bool supportsRoaming) noexcept :
Nl80211Wiphy::Nl80211Wiphy(uint32_t index, std::string_view name, std::vector<uint32_t> akmSuites, std::vector<uint32_t> cipherSuites, std::unordered_map<nl80211_band, Nl80211WiphyBand> bands, std::vector<nl80211_iftype> supportedInterfaceTypes, bool supportsRoaming) noexcept :
Index(index),
Name(name),
AkmSuites(std::move(akmSuites)),
CipherSuites(std::move(cipherSuites)),
Bands(std::move(bands)),
SupportedInterfaceTypes(std::move(supportedInterfaceTypes)),
Expand Down Expand Up @@ -191,11 +193,29 @@ Nl80211Wiphy::Parse(struct nl_msg *nl80211Message) noexcept
}
}

// Process AKM suites.
// Note: NL80211_ATTR_AKM_SUITES describes the AKMs supported by the PHY (wiphy) and is not specific to an interface.
uint32_t *wiphyAkmSuites;
std::size_t wiphyNumAkmSuites = 0;
std::vector<uint32_t> akmSuites{};
if (wiphyAttributes[NL80211_ATTR_AKM_SUITES] != nullptr) {
wiphyAkmSuites = static_cast<uint32_t *>(nla_data(wiphyAttributes[NL80211_ATTR_AKM_SUITES]));
wiphyNumAkmSuites = static_cast<std::size_t>(nla_len(wiphyAttributes[NL80211_ATTR_AKM_SUITES])) / sizeof(*wiphyAkmSuites);
akmSuites = std::vector<uint32_t>(wiphyAkmSuites, wiphyAkmSuites + wiphyNumAkmSuites);
} else {
// Per nl80211 documentation, if this attribute is not present, userspace should assume all AKMs are supported.
akmSuites = Microsoft::Net::Wifi::AllIeee80211Akms;
}

// Process cipher suites.
uint32_t *wiphyCipherSuites;
auto wiphyNumCipherSuites = static_cast<std::size_t>(nla_len(wiphyAttributes[NL80211_ATTR_CIPHER_SUITES])) / sizeof(*wiphyCipherSuites);
wiphyCipherSuites = static_cast<uint32_t *>(nla_data(wiphyAttributes[NL80211_ATTR_CIPHER_SUITES]));
std::vector<uint32_t> cipherSuites(wiphyCipherSuites, wiphyCipherSuites + wiphyNumCipherSuites);
std::size_t wiphyNumCipherSuites = 0;
std::vector<uint32_t> cipherSuites{};
if (wiphyAttributes[NL80211_ATTR_CIPHER_SUITES] != nullptr) {
uint32_t *wiphyCipherSuites;
wiphyNumCipherSuites = static_cast<std::size_t>(nla_len(wiphyAttributes[NL80211_ATTR_CIPHER_SUITES])) / sizeof(*wiphyCipherSuites);
wiphyCipherSuites = static_cast<uint32_t *>(nla_data(wiphyAttributes[NL80211_ATTR_CIPHER_SUITES]));
cipherSuites = std::vector<uint32_t>(wiphyCipherSuites, wiphyCipherSuites + wiphyNumCipherSuites);
}

// Process supported interface types.
std::vector<nl80211_iftype> supportedInterfaceTypes{};
Expand All @@ -212,7 +232,7 @@ Nl80211Wiphy::Parse(struct nl_msg *nl80211Message) noexcept
// Process roaming support.
auto wiphySupportsRoaming = wiphyAttributes[NL80211_ATTR_ROAM_SUPPORT] != nullptr;

Nl80211Wiphy nl80211Wiphy{ wiphyIndex, wiphyName, std::move(cipherSuites), std::move(wiphyBandMap), std::move(supportedInterfaceTypes), wiphySupportsRoaming };
Nl80211Wiphy nl80211Wiphy{ wiphyIndex, wiphyName, std::move(akmSuites), std::move(cipherSuites), std::move(wiphyBandMap), std::move(supportedInterfaceTypes), wiphySupportsRoaming };
return nl80211Wiphy;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct Nl80211Wiphy
{
uint32_t Index;
std::string Name;
// TODO: Add parsing for AKM suites via NL80211_ATTR_AKM_SUITES (count), NL80211_ATTR_IFTYPE_AKM_SUITES,
// NL80211_IFTYPE_AKM_ATTR_IFTYPES, NL80211_IFTYPE_AKM_ATTR_SUITES.
std::vector<uint32_t> AkmSuites;
std::vector<uint32_t> CipherSuites;
std::unordered_map<nl80211_band, Nl80211WiphyBand> Bands;
std::vector<nl80211_iftype> SupportedInterfaceTypes;
Expand Down Expand Up @@ -75,7 +78,7 @@ private:
* @param index The wiphy index.
* @param name The wiphy name.
*/
Nl80211Wiphy(uint32_t index, std::string_view name, std::vector<uint32_t> cipherSuites, std::unordered_map<nl80211_band, Nl80211WiphyBand> bands, std::vector<nl80211_iftype> supportedInterfaceTypes, bool supportsRoaming) noexcept;
Nl80211Wiphy(uint32_t index, std::string_view name, std::vector<uint32_t> akmSuites, std::vector<uint32_t> cipherSuites, std::unordered_map<nl80211_band, Nl80211WiphyBand> bands, std::vector<nl80211_iftype> supportedInterfaceTypes, bool supportsRoaming) noexcept;

/**
* @brief Creates a new Nl80211Wiphy object, using the specified function to add an identifier to the message,
Expand Down
18 changes: 13 additions & 5 deletions src/linux/wifi/core/AccessPointControllerLinux.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
#include <format>
#include <ranges>

#include <microsoft/net/wifi/AccessPointControllerLinux.hxx>
#include <microsoft/net/netlink/nl80211/Netlink80211Wiphy.hxx>
#include <plog/Log.h>
#include <Wpa/IHostapd.hxx>
#include <Wpa/ProtocolHostapd.hxx>
#include <Wpa/WpaCommandStatus.hxx>
#include <Wpa/WpaResponseStatus.hxx>
#include <microsoft/net/netlink/nl80211/Netlink80211Wiphy.hxx>
#include <microsoft/net/wifi/AccessPointControllerLinux.hxx>

using namespace Microsoft::Net::Wifi;

Expand All @@ -29,6 +28,12 @@ Nl80211CipherSuiteToIeee80211CipherSuite(uint32_t nl80211CipherSuite) noexcept
return static_cast<Ieee80211CipherSuite>(nl80211CipherSuite);
}

Ieee80211AkmSuite
Nl80211AkmSuiteToIeee80211AkmSuite(uint32_t nl80211AkmSuite) noexcept
{
return static_cast<Ieee80211AkmSuite>(nl80211AkmSuite);
}

Ieee80211FrequencyBand
Nl80211BandToIeee80211FrequencyBand(nl80211_band nl80211Band) noexcept
{
Expand All @@ -48,7 +53,7 @@ std::vector<Ieee80211Protocol>
Nl80211WiphyToIeee80211Protocols(const Nl80211Wiphy& nl80211Wiphy)
{
// Ieee80211 B & G are always supported.
std::vector<Ieee80211Protocol> protocols{
std::vector<Ieee80211Protocol> protocols{
Ieee80211Protocol::B,
Ieee80211Protocol::G,
};
Expand All @@ -63,7 +68,6 @@ Nl80211WiphyToIeee80211Protocols(const Nl80211Wiphy& nl80211Wiphy)
// TODO: once Nl80211WiphyBand is updated to support HE (AX) and EHT (BE), add them here.
}


// Remove duplicates.
std::ranges::sort(protocols);
protocols.erase(std::ranges::begin(std::ranges::unique(protocols)), std::ranges::end(protocols));
Expand All @@ -89,6 +93,10 @@ AccessPointControllerLinux::GetCapabilities()
capabilities.FrequencyBands = std::vector<Ieee80211FrequencyBand>(std::size(wiphy->Bands));
std::ranges::transform(std::views::keys(wiphy->Bands), std::begin(capabilities.FrequencyBands), detail::Nl80211BandToIeee80211FrequencyBand);

// Convert AKM suites.
capabilities.AkmSuites = std::vector<Ieee80211AkmSuite>(std::size(wiphy->AkmSuites));
std::ranges::transform(wiphy->AkmSuites, std::begin(capabilities.AkmSuites), detail::Nl80211AkmSuiteToIeee80211AkmSuite);

// Convert cipher suites.
capabilities.CipherSuites = std::vector<Ieee80211CipherSuite>(std::size(wiphy->CipherSuites));
std::ranges::transform(wiphy->CipherSuites, std::begin(capabilities.CipherSuites), detail::Nl80211CipherSuiteToIeee80211CipherSuite);
Expand Down

0 comments on commit 9d3de96

Please sign in to comment.