Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Populate AKMs in capabilities portion of WifiEnumerateAccessPoints #126

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading