diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe')
20 files changed, 7181 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/EapContext.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/EapContext.h new file mode 100644 index 00000000..7e5391ca --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/EapContext.h @@ -0,0 +1,22 @@ +/** @file + Eap configuration data structure definitions for EAP connections. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_EAP_CONTEXT_H__ +#define __EFI_WIFI_EAP_CONTEXT_H__ + +typedef struct { + + BOOLEAN IsEncrypted; + CHAR16 EncryptPassword[PASSWORD_STORAGE_SIZE]; + UINTN KeySize; + UINT8 KeyData[1]; + +} EFI_EAP_PRIVATE_KEY; + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf new file mode 100644 index 00000000..5d84cf5f --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.inf @@ -0,0 +1,81 @@ +## @file +# WiFi Connection Manager. +# +# This module is an example of how to make use of UEFI WiFi connection capabilities. +# User can scan, connect and diconnect to networks through UI operations. +# +# Supported networks include: +# 1). Open Network +# 2). WPA2 Personal Network +# 3). EAP Networks (EAP-TLS, EAP-TTLS/MSCHAPv2 and PEAPv0/MSCHAPv2) +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WifiConnectionManagerDxe + FILE_GUID = c6df98f2-5ec0-4a94-8c11-9a9828ef03f2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 0.1 + ENTRY_POINT = WifiMgrDxeDriverEntryPoint + +[Sources] + WifiConnectionMgrDxe.h + WifiConnectionMgrDriverBinding.h + WifiConnectionMgrConfig.h + WifiConnectionMgrMisc.h + WifiConnectionMgrImpl.h + WifiConnectionMgrConfigNVDataStruct.h + WifiConnectionMgrHiiConfigAccess.h + WifiConnectionMgrComponentName.h + WifiConnectionMgrFileUtil.h + WifiConnectionMgrDriver.c + WifiConnectionMgrComponentName.c + WifiConnectionMgrMisc.c + WifiConnectionMgrHiiConfigAccess.c + WifiConnectionMgrImpl.c + WifiConnectionMgrFileUtil.c + WifiConnectionManagerDxeStrings.uni + WifiConnectionManagerDxe.vfr + EapContext.h + WifiConnectionMgrConfigHii.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + DevicePathLib + DebugLib + HiiLib + PrintLib + UefiHiiServicesLib + NetLib + FileExplorerLib + +[Protocols] + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiWiFi2ProtocolGuid ## TO_START + gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES + gEfiSupplicantProtocolGuid ## SOMETIMES_CONSUMES + gEfiEapConfigurationProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gWifiConfigGuid ## PRODUCES ## GUID + gEfiIfrTianoGuid ## CONSUMES ## GUID (Extended IFR Guid Opcode) + gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES ## GUID # Indicate the current media state status + +[Depex] + gEfiHiiConfigRoutingProtocolGuid diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr new file mode 100644 index 00000000..23c1551d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxe.vfr @@ -0,0 +1,347 @@ +/** @file + Vfr files used in WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrConfigNVDataStruct.h" + +#define EFI_NETWORK_DEVICE_CLASS 0x04 + +formset + guid = WIFI_CONNECTION_MANAGER_CONFIG_GUID, + title = STRING_TOKEN(STR_WIFI_MGR_FORM_TITLE), + help = STRING_TOKEN(STR_WIFI_MGR_FORM_HELP), + class = EFI_NETWORK_DEVICE_CLASS, + subclass = 0x03, + + varstore WIFI_MANAGER_IFR_NVDATA, + varid = MANAGER_VARSTORE_ID, + name = WIFI_MANAGER_IFR_NVDATA, + guid = WIFI_CONNECTION_MANAGER_CONFIG_GUID; + + form formid = FORMID_MAC_SELECTION, + title = STRING_TOKEN(STR_WIFI_MAC_FORM_TITLE); + + suppressif TRUE; + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + key = KEY_MAC_LIST; + endif; + + label LABEL_MAC_ENTRY; + label LABEL_END; + endform; + + form formid = FORMID_WIFI_MAINPAGE, + title = STRING_TOKEN(STR_NETWORK_MANAGEMENT_TITLE); + + text + help = STRING_TOKEN(STR_MAC_ADDRESS_HELP), // Help string + text = STRING_TOKEN(STR_MAC_ADDRESS_TITLE), // Prompt string + text = STRING_TOKEN(STR_MAC_ADDRESS); // TextTwo + + text + help = STRING_TOKEN(STR_NULL_STRING), // Help string + text = STRING_TOKEN(STR_CONNECTION_INFO), // Prompt string + text = STRING_TOKEN(STR_CONNECTED_SSID); // TextTwo; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_NETWORK_LIST, + prompt = STRING_TOKEN(STR_NETWORK_LIST), + help = STRING_TOKEN(STR_NETWORK_LIST_HELP), + flags = INTERACTIVE, + key = KEY_NETWORK_LIST; + + goto FORMID_WIFI_SETTINGS, + prompt = STRING_TOKEN(STR_WIFI_SETTINGS), + help = STRING_TOKEN(STR_WIFI_SETTINGS_HELP), + flags = INTERACTIVE, + key = KEY_WIFI_SETTINGS; + + action + questionid = KEY_REFRESH_TITLE_CONNECTION_STATUS, + prompt = STRING_TOKEN(STR_NULL_STRING), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + config = STRING_TOKEN(STR_NULL_STRING), + refreshguid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID, + endaction; + + endform; + + form formid = FORMID_NETWORK_LIST, + title = STRING_TOKEN(STR_NETWORK_LIST); + + numeric varid = WIFI_MANAGER_IFR_NVDATA.ProfileCount, + prompt = STRING_TOKEN(STR_REFRESH_NETWORK_COUNT), + help = STRING_TOKEN(STR_REFRESH_NETWORK_COUNT_HELP), + flags = INTERACTIVE | READ_ONLY, + key = KEY_REFRESH_NETWORK_LIST, + minimum = 0, + maximum = 0xffffffff, + step = 0, + default = 0, + refreshguid = WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID, + endnumeric; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + label LABEL_NETWORK_LIST_ENTRY; + label LABEL_END; + endform; + + form formid = FORMID_CONNECT_NETWORK, + title = STRING_TOKEN(STR_NETWORK_CONFIGURATION); + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CONNECT_STATUS_TITLE_HELP), // Help string + text = STRING_TOKEN(STR_CONNECT_STATUS_TITLE), // Prompt string + text = STRING_TOKEN(STR_CONNECT_STATUS); // TextTwo + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SSID_HELP), // Help string + text = STRING_TOKEN(STR_SSID_TITLE), // Prompt string + text = STRING_TOKEN(STR_SSID); // TextTwo + + text + help = STRING_TOKEN(STR_SECURITY_TYPE_HELP), // Help string + text = STRING_TOKEN(STR_SECURITY_TYPE_TITLE), // Prompt string + text = STRING_TOKEN(STR_SECURITY_TYPE); // TextTwo + + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.SecurityType == SECURITY_TYPE_WPA2_PERSONAL; + password varid = WIFI_MANAGER_IFR_NVDATA.Password, + prompt = STRING_TOKEN(STR_PASSWORD), + help = STRING_TOKEN(STR_PASSWORD_HELP), + flags = INTERACTIVE, + key = KEY_PASSWORD_CONNECT_NETWORK, + minsize = PASSWORD_MIN_LEN, + maxsize = PASSWORD_MAX_LEN, + endpassword; + endif; + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE; + + oneof varid = WIFI_MANAGER_IFR_NVDATA.EapAuthMethod, + questionid = KEY_EAP_AUTH_METHOD_CONNECT_NETWORK, + prompt = STRING_TOKEN(STR_EAP_AUTH_METHOD), + help = STRING_TOKEN(STR_EAP_AUTH_METHOD_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_TTLS), value = EAP_AUTH_METHOD_TTLS, flags = DEFAULT; + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_PEAP), value = EAP_AUTH_METHOD_PEAP, flags = 0; + option text = STRING_TOKEN(STR_EAP_AUTH_METHOD_TLS), value = EAP_AUTH_METHOD_TLS, flags = 0; + endoneof; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TLS + EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CA_CERT), + help = STRING_TOKEN(STR_EAP_ENROLL_CA_CERT_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_CA_CERT_CONNECT_NETWORK; + + suppressif NOT ideqval WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TLS; + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_CERT), + help = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_CERT_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK; + + goto FORMID_ENROLL_PRIVATE_KEY, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY), + help = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY_HELP), + flags = INTERACTIVE, + key = KEY_ENROLL_PRIVATE_KEY_CONNECT_NETWORK; + + endif; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + oneof varid = WIFI_MANAGER_IFR_NVDATA.EapSecondAuthMethod, + questionid = KEY_EAP_SEAUTH_METHOD_CONNECT_NETWORK, + prompt = STRING_TOKEN(STR_EAP_SEAUTH_METHOD), + help = STRING_TOKEN(STR_EAP_SEAUTH_METHOD_HELP), + flags = INTERACTIVE, + option text = STRING_TOKEN(STR_EAP_SEAUTH_METHOD_MSCHAPV2), value = EAP_SEAUTH_METHOD_MSCHAPV2, flags = DEFAULT; + endoneof; + endif; + + string varid = WIFI_MANAGER_IFR_NVDATA.EapIdentity, + prompt = STRING_TOKEN(STR_EAP_IDENTITY), + help = STRING_TOKEN(STR_EAP_IDENTITY_HELP), + flags = INTERACTIVE, + key = KEY_EAP_IDENTITY_CONNECT_NETWORK, + minsize = 6, + maxsize = EAP_IDENTITY_LEN, + endstring; + + suppressif NOT ideqvallist WIFI_MANAGER_IFR_NVDATA.EapAuthMethod == EAP_AUTH_METHOD_TTLS + EAP_AUTH_METHOD_PEAP; + + password varid = WIFI_MANAGER_IFR_NVDATA.EapPassword, + prompt = STRING_TOKEN(STR_EAP_PASSWORD), + help = STRING_TOKEN(STR_EAP_PASSWORD_HELP), + flags = INTERACTIVE, + key = KEY_EAP_PASSWORD_CONNECT_NETWORK, + minsize = 0, + maxsize = PASSWORD_MAX_LEN, + endpassword; + endif; + endif; + endif; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_CONNECT_NOW_HELP), + text = STRING_TOKEN(STR_CONNECT_NOW), + flags = INTERACTIVE, + key = KEY_CONNECT_ACTION; + + action + questionid = KEY_REFRESH_CONNECT_CONFIGURATION, + prompt = STRING_TOKEN(STR_NULL_STRING), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + config = STRING_TOKEN(STR_NULL_STRING), + refreshguid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID, + endaction; + + endform; + + form formid = FORMID_ENROLL_CERT, + title = STRING_TOKEN(STR_EAP_ENROLL_CERT); + + goto FORMID_ENROLL_CERT, + prompt = STRING_TOKEN(STR_EAP_ENROLL_CERT_FROM_FILE), + help = STRING_TOKEN(STR_EAP_ENROLL_CERT_FROM_FILE_HELP), + flags = INTERACTIVE, + key = KEY_EAP_ENROLL_CERT_FROM_FILE; + + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_EAP_ENROLLED_CERT_NAME), + flags = INTERACTIVE, + key = KEY_ENROLLED_CERT_NAME; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_SAVE_CERT_TO_MEM; + + text + help = STRING_TOKEN(STR_NO_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_NO_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_NO_SAVE_CERT_TO_MEM; + + endform; + + form formid = FORMID_ENROLL_PRIVATE_KEY, + title = STRING_TOKEN(STR_EAP_ENROLL_CLIENT_KEY); + + goto FORMID_ENROLL_PRIVATE_KEY, + prompt = STRING_TOKEN(STR_EAP_ENROLL_KEY_FROM_FILE), + help = STRING_TOKEN(STR_EAP_ENROLL_KEY_FROM_FILE_HELP), + flags = INTERACTIVE, + key = KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE; + + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_EAP_ENROLLED_PRIVATE_KEY_NAME), + flags = INTERACTIVE, + key = KEY_ENROLLED_PRIVATE_KEY_NAME; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + password varid = WIFI_MANAGER_IFR_NVDATA.PrivateKeyPassword, + prompt = STRING_TOKEN(STR_EAP_CLIENT_KEY_PASSWORD), + help = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + key = KEY_PRIVATE_KEY_PASSWORD, + minsize = 0, + maxsize = PASSWORD_MAX_LEN, + endpassword; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + text + help = STRING_TOKEN(STR_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_SAVE_PRIVATE_KEY_TO_MEM; + + text + help = STRING_TOKEN(STR_NO_SAVE_EXIT_HELP), + text = STRING_TOKEN(STR_NO_SAVE_EXIT), + flags = INTERACTIVE, + key = KEY_NO_SAVE_PRIVATE_KEY_TO_MEM; + + endform; + + form formid = FORMID_WIFI_SETTINGS, + title = STRING_TOKEN(STR_WIFI_SETTINGS_FORM_TITLE); + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_HIDDEN_NETWORK_LIST, + prompt = STRING_TOKEN(STR_HIDDEN_NETWORK), + help = STRING_TOKEN(STR_HIDDEN_NETWORK_HELP), + flags = INTERACTIVE, + key = KEY_HIDDEN_NETWORK; + + endform; + + form formid = FORMID_HIDDEN_NETWORK_LIST, + title = STRING_TOKEN(STR_HIDDEN_NETWORK_FORM_TITLE); + + string + varid = WIFI_MANAGER_IFR_NVDATA.SSId, + prompt = STRING_TOKEN(STR_SSID_TITLE), + help = STRING_TOKEN(STR_SSID_HELP), + flags = INTERACTIVE, + minsize = SSID_MIN_LEN, + maxsize = SSID_MAX_LEN, + endstring; + + text + help = STRING_TOKEN(STR_ADD_HIDDEN_NETWORK_HELP), + text = STRING_TOKEN(STR_ADD_HIDDEN_NETWORK), + flags = INTERACTIVE, + key = KEY_ADD_HIDDEN_NETWORK; + + subtitle text = STRING_TOKEN(STR_NULL_STRING); + subtitle text = STRING_TOKEN(STR_HIDDEN_NETWORK_LIST); + + label LABEL_HIDDEN_NETWORK_ENTRY; + label LABEL_END; + + text + help = STRING_TOKEN(STR_REMOVE_HIDDEN_NETWORK_HELP), + text = STRING_TOKEN(STR_REMOVE_HIDDEN_NETWORK), + flags = INTERACTIVE, + key = KEY_REMOVE_HIDDEN_NETWORK; + + endform; + +endformset; diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni new file mode 100644 index 00000000..187e5047 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionManagerDxeStrings.uni @@ -0,0 +1,103 @@ +// /** @file
+// String definitions for WiFi Connection Manager Forms.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#langdef en-US "English"
+
+#string STR_WIFI_MGR_FORM_TITLE #language en-US "Wi-Fi Configuration"
+#string STR_WIFI_MGR_FORM_HELP #language en-US "Configure the Wi-Fi parameters."
+
+#string STR_WIFI_MAC_FORM_TITLE #language en-US "MAC Selection"
+#string STR_WIFI_MAC_FORM_HELP #language en-US "Select a Nic"
+
+#string STR_MAC_ADDRESS_TITLE #language en-US "MAC Address"
+#string STR_MAC_ADDRESS #language en-US "88-88-88-88-88-87"
+#string STR_MAC_ADDRESS_HELP #language en-US "MAC Address"
+#string STR_CONNECTION_INFO #language en-US "Disconnected"
+#string STR_CONNECTED_SSID #language en-US ""
+#string STR_NULL_STRING #language en-US ""
+
+#string STR_NETWORK_MANAGEMENT_TITLE #language en-US "Wi-Fi Network Management"
+#string STR_NETWORK_LIST #language en-US "Wi-Fi Network List"
+#string STR_NETWORK_LIST_HELP #language en-US "Available Network List"
+#string STR_NETWORK_CONFIGURATION #language en-US "Wi-Fi Network Configuration"
+
+#string STR_SSID_TITLE #language en-US "SSID"
+#string STR_SSID #language en-US ""
+#string STR_SSID_HELP #language en-US "SSID Length: 1 - 32 characters"
+#string STR_SECURITY_TYPE_TITLE #language en-US "Security"
+#string STR_SECURITY_TYPE #language en-US ""
+#string STR_SECURITY_TYPE_HELP #language en-US "Network Security Type"
+
+#string STR_EAP_AUTH_METHOD #language en-US "EAP Authentication Method"
+#string STR_EAP_AUTH_METHOD_HELP #language en-US "EAP Authentication Method"
+#string STR_EAP_SEAUTH_METHOD #language en-US "EAP Second Authentication Method"
+#string STR_EAP_SEAUTH_METHOD_HELP #language en-US "EAP Second Authentication Method"
+#string STR_SECURITY_NONE #language en-US "Open"
+#string STR_SECURITY_WEP #language en-US "WEP"
+#string STR_SECURITY_WPA_PERSONAL #language en-US "WPA-Personal"
+#string STR_SECURITY_WPA_ENTERPRISE #language en-US "WPA-Enterprise"
+#string STR_SECURITY_WPA2_PERSONAL #language en-US "WPA2-Personal"
+#string STR_SECURITY_WPA2_ENTERPRISE #language en-US "WPA2-Enterprise"
+#string STR_SECURITY_UNKNOWN #language en-US "Unknown"
+#string STR_EAP_AUTH_METHOD_TLS #language en-US "EAPTLS"
+#string STR_EAP_AUTH_METHOD_TTLS #language en-US "TTLS"
+#string STR_EAP_AUTH_METHOD_PEAP #language en-US "PEAP"
+#string STR_EAP_SEAUTH_METHOD_MSCHAPV2 #language en-US "MSCHAPv2"
+#string STR_EAP_SEAUTH_METHOD_GTC #language en-US "GTC"
+
+#string STR_PASSWORD #language en-US "Password"
+#string STR_PASSWORD_HELP #language en-US "Password Length: 8 - 63 characters"
+#string STR_CONNECT_STATUS_TITLE #language en-US "Connection Status:"
+#string STR_CONNECT_STATUS_TITLE_HELP #language en-US ""
+#string STR_CONNECT_STATUS #language en-US ""
+#string STR_CONNECT_STATUS_HELP #language en-US ""
+
+#string STR_CONNECT_NOW #language en-US "Connect to network now"
+#string STR_CONNECT_NOW_HELP #language en-US ""
+#string STR_DISCONNECT_NOW #language en-US "Disconnect from this network"
+#string STR_DISCONNECT_NOW_HELP #language en-US ""
+#string STR_REFRESH_NETWORK_COUNT #language en-US "Number of Networks"
+#string STR_REFRESH_NETWORK_COUNT_HELP #language en-US "The number of current available networks around"
+
+#string STR_EAP_IDENTITY #language en-US "Identity"
+#string STR_EAP_IDENTITY_HELP #language en-US "It is used to query the identity of the peer."
+#string STR_EAP_PASSWORD #language en-US "EAP Password"
+#string STR_EAP_PASSWORD_HELP #language en-US "Password Length: 1 - 63 characters"
+
+#string STR_SAVE_EXIT #language en-US "Commit Changes and Exit"
+#string STR_SAVE_EXIT_HELP #language en-US ""
+#string STR_NO_SAVE_EXIT #language en-US "Discard Changes and Exit"
+#string STR_NO_SAVE_EXIT_HELP #language en-US ""
+
+#string STR_EAP_ENROLL_CERT #language en-US "Enroll Certificate"
+#string STR_EAP_ENROLL_CA_CERT #language en-US "Enroll CA Cert"
+#string STR_EAP_ENROLL_CA_CERT_HELP #language en-US ""
+#string STR_EAP_ENROLL_CLIENT_CERT #language en-US "Enroll Client Cert"
+#string STR_EAP_ENROLL_CLIENT_CERT_HELP #language en-US ""
+#string STR_EAP_ENROLL_CLIENT_KEY #language en-US "Enroll Client Private Key"
+#string STR_EAP_ENROLL_CLIENT_KEY_HELP #language en-US ""
+#string STR_EAP_ENROLL_CERT_FROM_FILE #language en-US "Enroll Cert Using File"
+#string STR_EAP_ENROLL_CERT_FROM_FILE_HELP #language en-US ""
+#string STR_EAP_ENROLL_KEY_FROM_FILE #language en-US "Enroll Private Key Using File"
+#string STR_EAP_ENROLL_KEY_FROM_FILE_HELP #language en-US ""
+#string STR_EAP_CLIENT_KEY_PASSWORD #language en-US "Client Private Key Password"
+#string STR_EAP_ENROLLED_CERT_NAME #language en-US ""
+#string STR_EAP_ENROLLED_PRIVATE_KEY_NAME #language en-US ""
+
+#string STR_WIFI_SETTINGS_FORM_TITLE #language en-US "Wi-Fi Settings"
+#string STR_WIFI_SETTINGS #language en-US "Wi-Fi Settings"
+#string STR_WIFI_SETTINGS_HELP #language en-US ""
+
+#string STR_HIDDEN_NETWORK_FORM_TITLE #language en-US "Hidden Network Configuration"
+#string STR_HIDDEN_NETWORK #language en-US "Hidden Network Configuration"
+#string STR_HIDDEN_NETWORK_HELP #language en-US ""
+#string STR_ADD_HIDDEN_NETWORK_HELP #language en-US "Hidden Network List won't be saved in Storage, they will be cleaned after Reset!"
+#string STR_ADD_HIDDEN_NETWORK #language en-US "Add Hidden Network"
+#string STR_HIDDEN_NETWORK_LIST #language en-US "Hidden Network List"
+#string STR_REMOVE_HIDDEN_NETWORK_HELP #language en-US ""
+#string STR_REMOVE_HIDDEN_NETWORK #language en-US "Remove Hidden Network"
diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c new file mode 100644 index 00000000..f8dc2445 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.c @@ -0,0 +1,185 @@ +/** @file + UEFI Component Name(2) protocol implementation for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrDxe.h" + +extern EFI_GUID mEfiWifiMgrPrivateGuid; + +/// +/// Component Name Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME_PROTOCOL gWifiMgrDxeComponentName = { + (EFI_COMPONENT_NAME_GET_DRIVER_NAME) WifiMgrDxeComponentNameGetDriverName, + (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) WifiMgrDxeComponentNameGetControllerName, + "eng" +}; + +/// +/// Component Name 2 Protocol instance +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_COMPONENT_NAME2_PROTOCOL gWifiMgrDxeComponentName2 = { + WifiMgrDxeComponentNameGetDriverName, + WifiMgrDxeComponentNameGetControllerName, + "en" +}; + +/// +/// Table of driver names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mWifiMgrDxeDriverNameTable[] = { + { + "eng;en", + L"UEFI WiFi Connection Manager" + }, + { + NULL, + NULL + } +}; + +/// +/// Table of controller names +/// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_UNICODE_STRING_TABLE mWifiMgrDxeControllerNameTable[] = { + { + "eng;en", + L"UEFI WiFi Connection Manager Controller" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mWifiMgrDxeDriverNameTable, + DriverName, + (BOOLEAN)(This != &gWifiMgrDxeComponentName2) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS Status; + WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrPrivate; + + // + // ChildHandle must be NULL for a Device Driver + // + if (ControllerHandle == NULL || ChildHandle != NULL) { + return EFI_UNSUPPORTED; + } + + // + // Check Controller's handle + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + (VOID **) &WifiMgrPrivate, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mWifiMgrDxeControllerNameTable, + ControllerName, + (BOOLEAN)(This != &gWifiMgrDxeComponentName2) + ); +} diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h new file mode 100644 index 00000000..2bde4202 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrComponentName.h @@ -0,0 +1,93 @@ +/** @file + UEFI Component Name(2) protocol implementation for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_COMPONENT_NAME__ +#define __EFI_WIFI_COMPONENT_NAME__ + +/** + Retrieves a Unicode string that is the user-readable name of the EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param Language A pointer to a three-character ISO 639-2 language identifier. + This is the language of the driver name that that the caller + is requesting, and it must match one of the languages specified + in SupportedLanguages. The number of languages supported by a + driver is up to the driver writer. + @param DriverName A pointer to the Unicode string to return. This Unicode string + is the name of the driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by This + and the language specified by Language was returned + in DriverName. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER DriverName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by an EFI Driver. + + @param This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. + @param ControllerHandle The handle of a controller that the driver specified by + This is managing. This handle specifies the controller + whose name is to be returned. + @param ChildHandle The handle of the child controller to retrieve the name + of. This is an optional parameter that may be NULL. It + will be NULL for device drivers. It will also be NULL + for a bus drivers that wish to retrieve the name of the + bus controller. It will not be NULL for a bus driver + that wishes to retrieve the name of a child controller. + @param Language A pointer to a three character ISO 639-2 language + identifier. This is the language of the controller name + that the caller is requesting, and it must match one + of the languages specified in SupportedLanguages. The + number of languages supported by a driver is up to the + driver writer. + @param ControllerName A pointer to the Unicode string to return. This Unicode + string is the name of the controller specified by + ControllerHandle and ChildHandle in the language specified + by Language, from the point of view of the driver specified + by This. + + @retval EFI_SUCCESS The Unicode string for the user-readable name in the + language specified by Language for the driver + specified by This was returned in DriverName. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER Language is NULL. + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + @retval EFI_UNSUPPORTED The driver specified by This is not currently managing + the controller specified by ControllerHandle and + ChildHandle. + @retval EFI_UNSUPPORTED The driver specified by This does not support the + language specified by Language. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME2_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h new file mode 100644 index 00000000..1a93b81c --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfig.h @@ -0,0 +1,68 @@ +/** @file + Define network structure used by the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _WIFI_MGR_CONFIG_H_ +#define _WIFI_MGR_CONFIG_H_ + +#include "WifiConnectionMgrConfigNVDataStruct.h" + +extern UINT8 WifiConnectionManagerDxeBin[]; +extern UINT8 WifiConnectionManagerDxeStrings[]; + +typedef struct { + UINT32 Signature; + + // + // Link to the current profile list in NIC device data (WIFI_MGR_DEVICE_DATA) + // + LIST_ENTRY Link; + + UINT32 NicIndex; + UINT32 ProfileIndex; // The unique identifier for network profile, starts from 1 + CHAR16 SSId[SSID_STORAGE_SIZE]; + CHAR16 Password[PASSWORD_STORAGE_SIZE]; + + UINT8 SecurityType; + UINT8 EapAuthMethod; + + CHAR16 CACertName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *CACertData; + UINTN CACertSize; + CHAR16 ClientCertName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *ClientCertData; + UINTN ClientCertSize; + CHAR16 PrivateKeyName[WIFI_FILENAME_STR_MAX_SIZE]; + VOID *PrivateKeyData; + UINTN PrivateKeyDataSize; + CHAR16 PrivateKeyPassword[PASSWORD_STORAGE_SIZE]; //Password to protect private key file + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + CHAR16 EapPassword[PASSWORD_STORAGE_SIZE]; + UINT8 EapSecondAuthMethod; + + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + BOOLEAN IsAvailable; + EFI_80211_NETWORK Network; + UINT8 NetworkQuality; + EFI_STRING_ID TitleToken; +} WIFI_MGR_NETWORK_PROFILE; + +#define WIFI_MGR_PROFILE_SIGNATURE SIGNATURE_32 ('W','M','N','P') + +#pragma pack(1) +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; +#pragma pack() + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h new file mode 100644 index 00000000..3b614e7d --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigHii.h @@ -0,0 +1,29 @@ +/** @file + Module level GUIDs used in WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __WIFI_CONFIG_HII_GUID_H__ +#define __WIFI_CONFIG_HII_GUID_H__ + +// {36AF7790-0C2F-4055-9D3D-DB72A44953CB} +#define WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID \ + { \ + 0xc5f3c7f9, 0xfb9d, 0x49f1, { 0xbe, 0x67, 0x8b, 0xad, 0x20, 0xa7, 0xc6, 0xac } \ + } + +#define WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID \ + { \ + 0xe5faf2b2, 0x5ecc, 0x44ac, { 0x91, 0x75, 0xfb, 0x78, 0xb2, 0x8a, 0x59, 0x6c } \ + } + +#define WIFI_CONFIG_MAIN_FORM_REFRESH_GUID \ + { \ + 0xde609972, 0xcbcc, 0x4e82, { 0x8b, 0x3e, 0x6a, 0xc5, 0xcf, 0x56, 0x73, 0x8d } \ + } + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h new file mode 100644 index 00000000..9e353c62 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrConfigNVDataStruct.h @@ -0,0 +1,152 @@ +/** @file + Define IFR NVData structures used by the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _WIFI_NVDATASTRUC_H_ +#define _WIFI_NVDATASTRUC_H_ + +#include <Guid/WifiConnectionManagerConfigHii.h> +#include "WifiConnectionMgrConfigHii.h" + +#define MANAGER_VARSTORE_ID 0x0802 + +#define WIFI_STR_MAX_SIZE 224 +#define WIFI_FILENAME_STR_MAX_SIZE 224 +#define WIFI_MGR_MAX_MAC_STRING_LEN 96 + +#define SSID_MIN_LEN 1 +#define SSID_MAX_LEN 32 +#define SSID_STORAGE_SIZE 33 + +#define PASSWORD_MIN_LEN 8 +#define PASSWORD_MAX_LEN 63 +#define PASSWORD_STORAGE_SIZE 64 + +#define EAP_IDENTITY_LEN 63 +#define EAP_IDENTITY_SIZE 64 + +#define FORMID_NONE_FORM 0 +#define FORMID_MAC_SELECTION 1 +#define FORMID_WIFI_MAINPAGE 2 +#define FORMID_NETWORK_LIST 3 +#define FORMID_CONNECT_NETWORK 4 +#define FORMID_ENROLL_CERT 5 +#define FORMID_CA_LIST 6 +#define FORMID_ENROLL_PRIVATE_KEY 7 +#define FORMID_PRIVATE_KEY_LIST 8 +#define FORMID_WIFI_SETTINGS 9 +#define FORMID_HIDDEN_NETWORK_LIST 10 + +// +// Mac List Form Key +// +#define KEY_MAC_LIST 0x100 + +// +// Main Form Key +// +#define KEY_REFRESH_TITLE_CONNECTION_STATUS 0x101 + +// +// Network List Form Key +// +#define KEY_NETWORK_LIST 0x102 +#define KEY_REFRESH_NETWORK_LIST 0x103 +#define KEY_WIFI_SETTINGS 0x104 + +// +// Connect Network Form Key +// +#define KEY_PASSWORD_CONNECT_NETWORK 0x201 +#define KEY_CONNECT_ACTION 0x202 +#define KEY_REFRESH_CONNECT_CONFIGURATION 0x203 +#define KEY_EAP_AUTH_METHOD_CONNECT_NETWORK 0x204 +#define KEY_EAP_SEAUTH_METHOD_CONNECT_NETWORK 0x205 +#define KEY_ENROLL_CA_CERT_CONNECT_NETWORK 0x206 +#define KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK 0x207 +#define KEY_ENROLL_PRIVATE_KEY_CONNECT_NETWORK 0x208 +#define KEY_EAP_IDENTITY_CONNECT_NETWORK 0x209 +#define KEY_EAP_PASSWORD_CONNECT_NETWORK 0x210 + +// +//Cert Form And Private Key Form +// +#define KEY_EAP_ENROLL_CERT_FROM_FILE 0x301 +#define KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE 0x302 +#define KEY_SAVE_CERT_TO_MEM 0x303 +#define KEY_NO_SAVE_CERT_TO_MEM 0x304 +#define KEY_SAVE_PRIVATE_KEY_TO_MEM 0x305 +#define KEY_NO_SAVE_PRIVATE_KEY_TO_MEM 0x306 +#define KEY_PRIVATE_KEY_PASSWORD 0x307 +#define KEY_ENROLLED_CERT_NAME 0x308 +#define KEY_ENROLLED_PRIVATE_KEY_NAME 0x309 + +// +// Hidden Network Configuration Form +// +#define KEY_HIDDEN_NETWORK 0x401 +#define KEY_ADD_HIDDEN_NETWORK 0x402 +#define KEY_REMOVE_HIDDEN_NETWORK 0x403 + +// +// Dynamic Lists +// +#define MAC_LIST_COUNT_MAX 255 +#define LABEL_MAC_ENTRY 0x1000 +#define KEY_MAC_ENTRY_BASE 0x1100 + +#define NETWORK_LIST_COUNT_MAX 4095 +#define LABEL_NETWORK_LIST_ENTRY 0x2000 +#define KEY_AVAILABLE_NETWORK_ENTRY_BASE 0x3000 + +#define HIDDEN_NETWORK_LIST_COUNT_MAX 255 +#define LABEL_HIDDEN_NETWORK_ENTRY 0x4000 +#define KEY_HIDDEN_NETWORK_ENTRY_BASE 0x4100 + +#define LABEL_END 0xffff + +// +// Network Security Type +// +#define SECURITY_TYPE_NONE 0 +#define SECURITY_TYPE_WPA_ENTERPRISE 1 +#define SECURITY_TYPE_WPA2_ENTERPRISE 2 +#define SECURITY_TYPE_WPA_PERSONAL 3 +#define SECURITY_TYPE_WPA2_PERSONAL 4 +#define SECURITY_TYPE_WEP 5 +#define SECURITY_TYPE_UNKNOWN 6 +#define SECURITY_TYPE_MAX 7 + +#define EAP_AUTH_METHOD_TTLS 0 +#define EAP_AUTH_METHOD_PEAP 1 +#define EAP_AUTH_METHOD_TLS 2 +#define EAP_AUTH_METHOD_MAX 3 + +#define EAP_SEAUTH_METHOD_MSCHAPV2 0 +#define EAP_SEAUTH_METHOD_MAX 1 + +#define HIDDEN_NETWORK_LIST_VAR_OFFSET ((UINT16) OFFSET_OF (WIFI_MANAGER_IFR_NVDATA, HiddenNetworkList)) + +#pragma pack(1) +typedef struct _WIFI_MANAGER_IFR_NVDATA { + + UINT32 ProfileCount; + CHAR16 SSId[SSID_STORAGE_SIZE]; + CHAR16 Password[PASSWORD_STORAGE_SIZE]; + CHAR16 PrivateKeyPassword[PASSWORD_STORAGE_SIZE]; + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + CHAR16 EapPassword[PASSWORD_STORAGE_SIZE]; + UINT8 SecurityType; + UINT8 EapAuthMethod; + UINT8 EapSecondAuthMethod; + UINT8 HiddenNetworkList[HIDDEN_NETWORK_LIST_COUNT_MAX]; + +} WIFI_MANAGER_IFR_NVDATA; +#pragma pack() + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c new file mode 100644 index 00000000..2c9fdbc1 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriver.c @@ -0,0 +1,616 @@ +/** @file + The driver binding protocol for the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrDxe.h" + +/// +/// Driver Binding Protocol instance +/// +EFI_DRIVER_BINDING_PROTOCOL gWifiMgrDxeDriverBinding = { + WifiMgrDxeDriverBindingSupported, + WifiMgrDxeDriverBindingStart, + WifiMgrDxeDriverBindingStop, + WIFI_MGR_DXE_VERSION, + NULL, + NULL +}; + +// +//The private global data for WiFi Connection Manager +// +WIFI_MGR_PRIVATE_DATA *mPrivate = NULL; + +// +//The private guid to identify WiFi Connection Manager +// +EFI_GUID mEfiWifiMgrPrivateGuid = EFI_WIFIMGR_PRIVATE_GUID; + +// +//The Hii config guids +// +EFI_GUID gWifiConfigFormSetGuid = WIFI_CONNECTION_MANAGER_CONFIG_GUID; +EFI_GUID mWifiConfigNetworkListRefreshGuid = WIFI_CONFIG_NETWORK_LIST_REFRESH_GUID; +EFI_GUID mWifiConfigConnectFormRefreshGuid = WIFI_CONFIG_CONNECT_FORM_REFRESH_GUID; +EFI_GUID mWifiConfigMainFormRefreshGuid = WIFI_CONFIG_MAIN_FORM_REFRESH_GUID; + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + + // + // Test for the wireless MAC connection 2 protocol + // + return gBS->OpenProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + NULL, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); +} + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + UINTN AddressSize; + WIFI_MGR_DEVICE_DATA *Nic; + EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + + Nic = NULL; + + // + //Open Protocols + // + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + (VOID**) &Wmp, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + (VOID**) &Supplicant, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + Supplicant = NULL; + } + + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + (VOID**) &EapConfig, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (EFI_ERROR (Status)) { + EapConfig = NULL; + } + + // + //Initialize Nic device data + // + Nic = AllocateZeroPool (sizeof (WIFI_MGR_DEVICE_DATA)); + if (Nic == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR1; + } + Nic->Signature = WIFI_MGR_DEVICE_DATA_SIGNATURE; + Nic->DriverHandle = This->DriverBindingHandle; + Nic->ControllerHandle = ControllerHandle; + Nic->Private = mPrivate; + Nic->Wmp = Wmp; + Nic->Supplicant = Supplicant; + Nic->EapConfig = EapConfig; + Nic->UserSelectedProfile = NULL; + Nic->OneTimeScanRequest = FALSE; + Nic->ScanTickTime = WIFI_SCAN_FREQUENCY; //Initialize the first scan + + if (Nic->Supplicant != NULL) { + WifiMgrGetSupportedSuites(Nic); + } + + InitializeListHead (&Nic->ProfileList); + + // + // Record the MAC address of the incoming NIC. + // + Status = NetLibGetMacAddress ( + ControllerHandle, + (EFI_MAC_ADDRESS*) &Nic->MacAddress, + &AddressSize + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + // + // Create and start the timer for the status check + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL | EVT_TIMER, + TPL_CALLBACK, + WifiMgrOnTimerTick, + Nic, + &Nic->TickTimer + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + Status = gBS->SetTimer (Nic->TickTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS(500)); + if (EFI_ERROR (Status)) { + goto ERROR3; + } + + Nic->ConnectState = WifiMgrDisconnected; + Nic->ScanState = WifiMgrScanFinished; + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + InsertTailList (&mPrivate->NicList, &Nic->Link); + Nic->NicIndex = mPrivate->NicCount ++; + if (mPrivate->CurrentNic == NULL) { + mPrivate->CurrentNic = Nic; + } + gBS->RestoreTPL (OldTpl); + + Status = gBS->InstallProtocolInterface ( + &ControllerHandle, + &mEfiWifiMgrPrivateGuid, + EFI_NATIVE_INTERFACE, + &Nic->WifiMgrIdentifier + ); + if (EFI_ERROR (Status)) { + goto ERROR4; + } + + return EFI_SUCCESS; + +ERROR4: + + gBS->SetTimer (Nic->TickTimer, TimerCancel, 0); + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + RemoveEntryList (&Nic->Link); + mPrivate->NicCount--; + gBS->RestoreTPL (OldTpl); + +ERROR3: + + gBS->CloseEvent (Nic->TickTimer); + +ERROR2: + + if (Nic->Supplicant != NULL) { + if (Nic->SupportedSuites.SupportedAKMSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedAKMSuites); + } + if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedSwCipherSuites); + } + if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedHwCipherSuites); + } + } + FreePool (Nic); + +ERROR1: + + if (Supplicant != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + if (EapConfig != NULL) { + gBS->CloseProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + } + + gBS->CloseProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); + + return Status; +} + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_PRIVATE_PROTOCOL *WifiMgrIdentifier; + WIFI_MGR_DEVICE_DATA *Nic; + + Status = gBS->OpenProtocol ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + (VOID **) &WifiMgrIdentifier, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + Nic = WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER (WifiMgrIdentifier); + if (Nic == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // Close Event + // + gBS->SetTimer (Nic->TickTimer, TimerCancel, 0); + gBS->CloseEvent (Nic->TickTimer); + + // + // Clean Supported Suites + // + if (Nic->Supplicant != NULL) { + if (Nic->SupportedSuites.SupportedAKMSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedAKMSuites); + } + if (Nic->SupportedSuites.SupportedSwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedSwCipherSuites); + } + if (Nic->SupportedSuites.SupportedHwCipherSuites != NULL) { + FreePool (Nic->SupportedSuites.SupportedHwCipherSuites); + } + } + + // + // Close Protocols + // + Status = gBS->UninstallProtocolInterface ( + ControllerHandle, + &mEfiWifiMgrPrivateGuid, + &Nic->WifiMgrIdentifier + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiWiFi2ProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + if (Nic->Supplicant != NULL) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiSupplicantProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + if (Nic->EapConfig != NULL) { + Status = gBS->CloseProtocol ( + ControllerHandle, + &gEfiEapConfigurationProtocolGuid, + Nic->DriverHandle, + Nic->ControllerHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + + // + // Remove this Nic from Nic list + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + RemoveEntryList (&Nic->Link); + mPrivate->NicCount--; + if (mPrivate->CurrentNic == Nic) { + mPrivate->CurrentNic = NULL; + } + + gBS->RestoreTPL (OldTpl); + + WifiMgrFreeProfileList (&Nic->ProfileList); + FreePool (Nic); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Device Controller has been Disconnected!\n")); + return EFI_SUCCESS; +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others An unexpected error occurred. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &gWifiMgrDxeDriverBinding, + ImageHandle, + &gWifiMgrDxeComponentName, + &gWifiMgrDxeComponentName2 + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Initialize the global private data structure. + // + mPrivate = AllocateZeroPool (sizeof (WIFI_MGR_PRIVATE_DATA)); + if (mPrivate == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR1; + } + mPrivate->Signature = WIFI_MGR_PRIVATE_DATA_SIGNATURE; + mPrivate->DriverHandle = ImageHandle; + InitializeListHead (&mPrivate->NicList); + mPrivate->NicCount = 0; + mPrivate->CurrentNic = NULL; + InitializeListHead (&mPrivate->HiddenNetworkList); + mPrivate->HiddenNetworkCount = 0; + + // + //Create events for page refresh + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &mWifiConfigNetworkListRefreshGuid, + &mPrivate->NetworkListRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR2; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &mWifiConfigConnectFormRefreshGuid, + &mPrivate->ConnectFormRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR3; + } + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrInternalEmptyFunction, + NULL, + &mWifiConfigMainFormRefreshGuid, + &mPrivate->MainPageRefreshEvent + ); + if (EFI_ERROR (Status)) { + goto ERROR4; + } + + Status = WifiMgrDxeConfigFormInit (mPrivate); + if (EFI_ERROR (Status)) { + goto ERROR5; + } + + return Status; + +ERROR5: + gBS->CloseEvent (mPrivate->MainPageRefreshEvent); + +ERROR4: + gBS->CloseEvent (mPrivate->ConnectFormRefreshEvent); + +ERROR3: + gBS->CloseEvent (mPrivate->NetworkListRefreshEvent); + +ERROR2: + if (mPrivate != NULL) { + FreePool (mPrivate); + mPrivate = NULL; + } + +ERROR1: + gBS->UninstallMultipleProtocolInterfaces ( + ImageHandle, + &gEfiDriverBindingProtocolGuid, + &gWifiMgrDxeDriverBinding, + &gEfiComponentNameProtocolGuid, + &gWifiMgrDxeComponentName, + &gEfiComponentName2ProtocolGuid, + &gWifiMgrDxeComponentName2, + NULL + ); + + return Status; +} diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h new file mode 100644 index 00000000..ed6d931a --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDriverBinding.h @@ -0,0 +1,142 @@ +/** @file + The driver binding protocol for the WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_DRIVER_BINDING__ +#define __EFI_WIFI_DRIVER_BINDING__ + +/** + Tests to see if this driver supports a given controller. If a child device is provided, + it further tests to see if this driver supports creating a handle for the specified child device. + + This function checks to see if the driver specified by This supports the device specified by + ControllerHandle. Drivers will typically use the device path attached to + ControllerHandle and/or the services from the bus I/O abstraction attached to + ControllerHandle to determine if the driver supports ControllerHandle. This function + may be called many times during platform initialization. In order to reduce boot times, the tests + performed by this function must be very small, and take as little time as possible to execute. This + function must not change the state of any hardware devices, and this function must be aware that the + device specified by ControllerHandle may already be managed by the same driver or a + different driver. This function must match its calls to AllocatePages() with FreePages(), + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). + Because ControllerHandle may have been previously started by the same driver, if a protocol is + already in the opened state, then it must not be closed with CloseProtocol(). This is required + to guarantee the state of ControllerHandle is not modified by this function. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to test. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For bus drivers, if this parameter is not NULL, then + the bus driver must determine if the bus controller specified + by ControllerHandle and the child controller specified + by RemainingDevicePath are both supported by this + bus driver. + + @retval EFI_SUCCESS The device specified by ControllerHandle and + RemainingDevicePath is supported by the driver specified by This. + @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by the driver + specified by This. + @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and + RemainingDevicePath is already being managed by a different + driver or an application that requires exclusive access. + Currently not implemented. + @retval EFI_UNSUPPORTED The device specified by ControllerHandle and + RemainingDevicePath is not supported by the driver specified by This. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Starts a device controller or a bus controller. + + The Start() function is designed to be invoked from the EFI boot service ConnectController(). + As a result, much of the error checking on the parameters to Start() has been moved into this + common boot service. It is legal to call Start() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE. + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned + EFI_DEVICE_PATH_PROTOCOL. + 3. Prior to calling Start(), the Supported() function for the driver specified by This must + have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle The handle of the controller to start. This handle + must support a protocol interface that supplies + an I/O abstraction to the driver. + @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This + parameter is ignored by device drivers, and is optional for bus + drivers. For a bus driver, if this parameter is NULL, then handles + for all the children of Controller are created by this driver. + If this parameter is not NULL and the first Device Path Node is + not the End of Device Path Node, then only the handle for the + child device specified by the first Device Path Node of + RemainingDevicePath is created by this driver. + If the first Device Path Node of RemainingDevicePath is + the End of Device Path Node, no child handle is created by this + driver. + + @retval EFI_SUCCESS The device was started. + @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented. + @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. + @retval Others The driver failded to start the device. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL + ); + +/** + Stops a device controller or a bus controller. + + The Stop() function is designed to be invoked from the EFI boot service DisconnectController(). + As a result, much of the error checking on the parameters to Stop() has been moved + into this common boot service. It is legal to call Stop() from other locations, + but the following calling restrictions must be followed, or the system behavior will not be deterministic. + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this + same driver's Start() function. + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid + EFI_HANDLE. In addition, all of these handles must have been created in this driver's + Start() function, and the Start() function must have called OpenProtocol() on + ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. + + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. + @param[in] ControllerHandle A handle to the device being stopped. The handle must + support a bus specific I/O protocol for the driver + to use to stop the device. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h new file mode 100644 index 00000000..b3f35bec --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrDxe.h @@ -0,0 +1,321 @@ +/** @file + The miscellaneous structure definitions for WiFi connection driver. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_MGR_DXE_H__ +#define __EFI_WIFI_MGR_DXE_H__ + +#include <Uefi.h> + +// +// Libraries +// +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/BaseLib.h> +#include <Library/UefiLib.h> +#include <Library/DevicePathLib.h> +#include <Library/DebugLib.h> +#include <Library/HiiLib.h> +#include <Library/NetLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiHiiServicesLib.h> +#include <Library/FileExplorerLib.h> + +// +// UEFI Driver Model Protocols +// +#include <Protocol/DriverBinding.h> +#include <Protocol/HiiDatabase.h> +#include <Protocol/HiiPackageList.h> +#include <Protocol/ComponentName2.h> +#include <Protocol/ComponentName.h> + +// +// Consumed Protocols +// +#include <Protocol/WiFi2.h> +#include <Protocol/AdapterInformation.h> +#include <Protocol/Supplicant.h> +#include <Protocol/SimpleNetwork.h> +#include <Protocol/SimpleFileSystem.h> +#include <Protocol/EapConfiguration.h> + +// +// Produced Protocols +// +#include <Protocol/HiiConfigAccess.h> + +// +// Guids +// +#include <Guid/ImageAuthentication.h> +#include <Guid/MdeModuleHii.h> +#include <Guid/WifiConnectionManagerConfigHii.h> + +// +// NvData struct definition +// +#include "WifiConnectionMgrConfigNVDataStruct.h" +#include "WifiConnectionMgrConfig.h" +#include "EapContext.h" +#include "WifiConnectionMgrConfigHii.h" + +// +// Driver Version +// +#define WIFI_MGR_DXE_VERSION 0xb + +#define OUI_IEEE_80211I 0xAC0F00 + +typedef enum { + Ieee80211PairwiseCipherSuiteUseGroupCipherSuite = 0, + Ieee80211PairwiseCipherSuiteWEP40 = 1, + Ieee80211PairwiseCipherSuiteTKIP = 2, + Ieee80211PairwiseCipherSuiteCCMP = 4, + Ieee80211PairwiseCipherSuiteWEP104 = 5, + Ieee80211PairwiseCipherSuiteBIP = 6, + //... +} IEEE_80211_PAIRWISE_CIPHER_SUITE; + +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_USE_GROUP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteUseGroupCipherSuite << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP40 (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteWEP40 << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_TKIP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteTKIP << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_CCMP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteCCMP << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP104 (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteWEP104 << 24)) +#define IEEE_80211_PAIRWISE_CIPHER_SUITE_BIP (OUI_IEEE_80211I | (Ieee80211PairwiseCipherSuiteBIP << 24)) + +typedef enum { + Ieee80211AkmSuite8021XOrPMKSA = 1, + Ieee80211AkmSuitePSK = 2, + Ieee80211AkmSuite8021XOrPMKSASHA256 = 5, + Ieee80211AkmSuitePSKSHA256 = 6 + //... +} IEEE_80211_AKM_SUITE; + +#define IEEE_80211_AKM_SUITE_8021X_OR_PMKSA (OUI_IEEE_80211I | (Ieee80211AkmSuite8021XOrPMKSA << 24)) +#define IEEE_80211_AKM_SUITE_PSK (OUI_IEEE_80211I | (Ieee80211AkmSuitePSK << 24)) +#define IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256 (OUI_IEEE_80211I | (Ieee80211AkmSuite8021XOrPMKSASHA256 << 24)) +#define IEEE_80211_AKM_SUITE_PSK_SHA256 (OUI_IEEE_80211I | (Ieee80211AkmSuitePSKSHA256 << 24)) + +// +// Protocol instances +// +extern EFI_DRIVER_BINDING_PROTOCOL gWifiMgrDxeDriverBinding; +extern EFI_COMPONENT_NAME2_PROTOCOL gWifiMgrDxeComponentName2; +extern EFI_COMPONENT_NAME_PROTOCOL gWifiMgrDxeComponentName; +extern EFI_HII_CONFIG_ACCESS_PROTOCOL gWifiMgrDxeHiiConfigAccess; + +// +// Private Context Data Structure +// +typedef enum { + WifiMgrDisconnected, + WifiMgrConnectingToAp, + WifiMgrConnectedToAp, + WifiMgrDisconnectingToAp, + WifiMgrConnectStateMaximum +} WIFI_MGR_CONNECT_STATE; + +typedef enum { + WifiMgrScanFinished, + WifiMgrScanning, + WifiMgrScanStateMaximum +} WIFI_MGR_SCAN_STATE; + +#define WIFI_SCAN_FREQUENCY 30 + +typedef struct _WIFI_MGR_SUPPORTED_SUITES { + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; +} WIFI_MGR_SUPPORTED_SUITES; + +#define EFI_WIFIMGR_PRIVATE_GUID \ + { \ + 0x99b7c019, 0x4789, 0x4829, { 0xa7, 0xbd, 0x0d, 0x4b, 0xaa, 0x62, 0x28, 0x72 } \ + } + +typedef struct _WIFI_MGR_PRIVATE_DATA WIFI_MGR_PRIVATE_DATA; + +typedef struct _WIFI_MGR_PRIVATE_PROTOCOL { + UINT32 Reserved; +} WIFI_MGR_PRIVATE_PROTOCOL; + +typedef struct _WIFI_MGR_FILE_CONTEXT { + EFI_FILE_HANDLE FHandle; + UINT16 *FileName; +} WIFI_MGR_FILE_CONTEXT; + +typedef enum { + FileTypeCACert, + FileTypeClientCert, + FileTypeMax +} WIFI_MGR_FILE_TYPE; + +typedef struct { + UINT32 Signature; + EFI_HANDLE DriverHandle; + EFI_HANDLE ControllerHandle; + EFI_EVENT TickTimer; + WIFI_MGR_PRIVATE_DATA *Private; + + // + // Pointers to consumed protocols + // + EFI_WIRELESS_MAC_CONNECTION_II_PROTOCOL *Wmp; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + + // + // Produced protocols + // + WIFI_MGR_PRIVATE_PROTOCOL WifiMgrIdentifier; + + // + // Private functions and data fields + // + LIST_ENTRY Link; // Link to the NicList in global private data structure. + UINT32 NicIndex; + EFI_80211_MAC_ADDRESS MacAddress; + WIFI_MGR_SUPPORTED_SUITES SupportedSuites; + EFI_ADAPTER_INFO_MEDIA_STATE LastLinkState; + + // + // The network is currently connected, connecting or disconnecting. + // Only one network can be operated at one time. + // + WIFI_MGR_NETWORK_PROFILE *CurrentOperateNetwork; + WIFI_MGR_NETWORK_PROFILE *ConnectPendingNetwork; + BOOLEAN HasDisconnectPendingNetwork; + + // + //Profile related data fields + // + LIST_ENTRY ProfileList; // List of WIFI_MGR_NETWORK_PROFILE + UINT32 AvailableCount; + UINT32 MaxProfileIndex; + WIFI_MGR_NETWORK_PROFILE *UserSelectedProfile; + + // + // Data fields for Hii functionlity + // + BOOLEAN OneTimeScanRequest; + BOOLEAN OneTimeConnectRequest; + BOOLEAN OneTimeDisconnectRequest; + WIFI_MGR_SCAN_STATE ScanState; + UINTN ScanTickTime; + WIFI_MGR_CONNECT_STATE ConnectState; + BOOLEAN ConnectStateChanged; +} WIFI_MGR_DEVICE_DATA; + +#define WIFI_MGR_DEVICE_DATA_SIGNATURE SIGNATURE_32 ('W','M','D','D') + +#define WIFI_MGR_DEVICE_DATA_FROM_IDENTIFIER(Identifier) \ + CR ( \ + Identifier, \ + WIFI_MGR_DEVICE_DATA, \ + WifiMgrIdentifier, \ + WIFI_MGR_DEVICE_DATA_SIGNATURE \ + ) + +typedef struct { + UINT32 Signature; + LIST_ENTRY Link; + CHAR16 SSId[SSID_STORAGE_SIZE]; +} WIFI_HIDDEN_NETWORK_DATA; + +#define WIFI_MGR_HIDDEN_NETWORK_SIGNATURE SIGNATURE_32 ('W','M','H','N') + +#define WIFI_MGR_HIDDEN_NETWORK_FROM_IDENTIFIER(Identifier) \ + CR ( \ + Identifier, \ + WIFI_HIDDEN_NETWORK_DATA, \ + WifiMgrIdentifier, \ + WIFI_MGR_HIDDEN_NETWORK_SIGNATURE \ + ) + +// +// Global private data struct +// +struct _WIFI_MGR_PRIVATE_DATA { + + UINT32 Signature; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE RegisteredHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + + UINT32 NicCount; + LIST_ENTRY NicList; + WIFI_MGR_DEVICE_DATA *CurrentNic; + + // + // Data fields for Hii functionlity + // + EFI_EVENT NetworkListRefreshEvent; // Event to refresh the network list form + EFI_EVENT ConnectFormRefreshEvent; // Event to refresh the connect form + EFI_EVENT MainPageRefreshEvent; // Event to refresh the main page + + // + //User Input Record + // + UINT8 SecurityType; + UINT8 EapAuthMethod; + UINT8 EapSecondAuthMethod; + CHAR16 EapIdentity[EAP_IDENTITY_SIZE]; + + WIFI_MGR_FILE_CONTEXT *FileContext; + WIFI_MGR_FILE_TYPE FileType; + + UINT32 HiddenNetworkCount; + LIST_ENTRY HiddenNetworkList; +}; + +#define WIFI_MGR_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('W','M','P','D') + +#define WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS(This) \ + CR ( \ + This, \ + WIFI_MGR_PRIVATE_DATA, \ + ConfigAccess, \ + WIFI_MGR_PRIVATE_DATA_SIGNATURE \ + ) +extern WIFI_MGR_PRIVATE_DATA *mPrivate; + +typedef enum { + TokenTypeGetNetworksToken, + TokenTypeConnectNetworkToken, + TokenTypeDisconnectNetworkToken, + TokenTypeMax, +} WIFI_MGR_MAC_CONFIG_TOKEN_TYPE; + +typedef union { + EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken; + EFI_80211_CONNECT_NETWORK_TOKEN *ConnectNetworkToken; + EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectNetworkToken; +} MAC_CONNECTION2_ADAPTER_TOKEN; + +typedef struct { + WIFI_MGR_DEVICE_DATA *Nic; + WIFI_MGR_MAC_CONFIG_TOKEN_TYPE Type; + MAC_CONNECTION2_ADAPTER_TOKEN Token; +} WIFI_MGR_MAC_CONFIG_TOKEN; + +// +// Include files with function prototypes +// +#include "WifiConnectionMgrDriverBinding.h" +#include "WifiConnectionMgrImpl.h" +#include "WifiConnectionMgrComponentName.h" +#include "WifiConnectionMgrHiiConfigAccess.h" +#include "WifiConnectionMgrMisc.h" +#include "WifiConnectionMgrFileUtil.h" + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c new file mode 100644 index 00000000..0005bcf8 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.c @@ -0,0 +1,303 @@ +/** @file + The file operation functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrFileUtil.h" + +CHAR16* mDerPemEncodedSuffix[] = { + L".cer", + L".der", + L".crt", + L".pem", + NULL +}; + +/** + This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix. + + @param[in] FileSuffix The suffix of the input certificate file + + @retval TRUE It's a DER/PEM-encoded certificate. + @retval FALSE It's NOT a DER/PEM-encoded certificate. + +**/ +BOOLEAN +IsDerPemEncodeCertificate ( + IN CONST CHAR16 *FileSuffix +) +{ + UINTN Index; + for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) { + if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) { + return TRUE; + } + } + return FALSE; +} + +/** + Read file content into BufferPtr, the size of the allocate buffer + is *FileSize plus AddtionAllocateSize. + + @param[in] FileHandle The file to be read. + @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. + @param[out] FileSize Size of input file + @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. + In case the buffer need to contain others besides the file content. + + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval others Unexpected error. + +**/ +EFI_STATUS +ReadFileContent ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize, + IN UINTN AddtionAllocateSize + ) +{ + UINTN BufferSize; + UINT64 SourceFileSize; + VOID *Buffer; + EFI_STATUS Status; + + if ((FileHandle == NULL) || (FileSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Buffer = NULL; + + // + // Get the file size + // + Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->SetPosition (FileHandle, 0); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize; + Buffer = AllocateZeroPool(BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BufferSize = (UINTN) SourceFileSize; + *FileSize = BufferSize; + + Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); + if (EFI_ERROR (Status) || BufferSize != *FileSize) { + FreePool (Buffer); + Buffer = NULL; + Status = EFI_BAD_BUFFER_SIZE; + goto ON_EXIT; + } + +ON_EXIT: + + *BufferPtr = Buffer; + return Status; +} + +/** + This function converts an input device structure to a Unicode string. + + @param[in] DevPath A pointer to the device path structure. + + @return A new allocated Unicode string that represents the device path. + +**/ +CHAR16 * +EFIAPI +DevicePathToStr ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +{ + return ConvertDevicePathToText ( + DevPath, + FALSE, + TRUE + ); +} + +/** + Extract filename from device path. The returned buffer is allocated using AllocateCopyPool. + The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL + means not enough memory resource. + + @param DevicePath Device path. + + @retval NULL Not enough memory resourece for AllocateCopyPool. + @retval Other A new allocated string that represents the file name. + +**/ +CHAR16 * +ExtractFileNameFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CHAR16 *String; + CHAR16 *MatchString; + CHAR16 *LastMatch; + CHAR16 *FileName; + UINTN Length; + + ASSERT(DevicePath != NULL); + + String = DevicePathToStr(DevicePath); + if (String == NULL) { + return NULL; + } + MatchString = String; + LastMatch = String; + FileName = NULL; + + while(MatchString != NULL){ + LastMatch = MatchString + 1; + MatchString = StrStr(LastMatch,L"\\"); + } + + Length = StrLen(LastMatch); + FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch); + if (FileName != NULL) { + *(FileName + Length) = 0; + } + + FreePool(String); + + return FileName; +} + +/** + Update the form base on the selected file. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + @param[in] FormId The form needs to display. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePage( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_FORM_ID FormId + ) +{ + CHAR16 *FileName; + EFI_STATUS Status; + + FileName = NULL; + + if (FilePath != NULL) { + FileName = ExtractFileNameFromDevicePath(FilePath); + } + if (FileName == NULL) { + // + // FileName = NULL has two cases: + // 1. FilePath == NULL, not select file. + // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource. + // In these two case, no need to update the form, and exit the caller function. + // + return TRUE; + } + + // + // Close the previous file handle before open a new one. + // + if (Private->FileContext->FHandle != NULL) { + Private->FileContext->FHandle->Close (Private->FileContext->FHandle); + } + Private->FileContext->FHandle = NULL; + + Status = EfiOpenFileByDevicePath ( + &FilePath, + &Private->FileContext->FHandle, + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + if (FormId == FORMID_ENROLL_CERT) { + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); + } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){ + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL); + } + } else { + + if (Private->FileContext->FileName != NULL) { + FreePool (Private->FileContext->FileName); + Private->FileContext->FileName = NULL; + } + Private->FileContext->FileName = FileName; + + if (FormId == FORMID_ENROLL_CERT) { + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), FileName, NULL); + } else if (FormId == FORMID_ENROLL_PRIVATE_KEY){ + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), FileName, NULL); + } + } + + return TRUE; +} + +/** + Update the CA form base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdateCAFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + return UpdatePage(Private, FilePath, FORMID_ENROLL_CERT); +} + +/** + Update the Private Key form base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePrivateKeyFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + return UpdatePage(Private, FilePath, FORMID_ENROLL_PRIVATE_KEY); +} + diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h new file mode 100644 index 00000000..21f70ec4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrFileUtil.h @@ -0,0 +1,71 @@ +/** @file + The file operation functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_MGR_FILE_UTIL__ +#define __EFI_WIFI_MGR_FILE_UTIL__ + +#include "WifiConnectionMgrDxe.h" + +/** + Read file content into BufferPtr, the size of the allocate buffer + is *FileSize plus AddtionAllocateSize. + + @param[in] FileHandle The file to be read. + @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. + @param[out] FileSize Size of input file + @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. + In case the buffer need to contain others besides the file content. + + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval others Unexpected error. + +**/ +EFI_STATUS +ReadFileContent ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize, + IN UINTN AddtionAllocateSize + ); + +/** + Update the CA cert base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdateCAFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ); + +/** + Update the Private Key base on the input file path info. + + @param[in] Private The pointer to the global private data structure. + @param[in] FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePrivateKeyFromFile ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c new file mode 100644 index 00000000..73fce8a8 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c @@ -0,0 +1,2017 @@ +/** @file + The Hii functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrDxe.h" + +CHAR16 mVendorStorageName[] = L"WIFI_MANAGER_IFR_NVDATA"; + +HII_VENDOR_DEVICE_PATH mWifiMgrDxeHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + WIFI_CONNECTION_MANAGER_CONFIG_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +// +// HII Config Access Protocol instance +// +GLOBAL_REMOVE_IF_UNREFERENCED +EFI_HII_CONFIG_ACCESS_PROTOCOL gWifiMgrDxeHiiConfigAccess = { + WifiMgrDxeHiiConfigAccessExtractConfig, + WifiMgrDxeHiiConfigAccessRouteConfig, + WifiMgrDxeHiiConfigAccessCallback +}; + +CHAR16* mSecurityType[] = { + L"OPEN ", + L"WPA-Enterprise ", + L"WPA2-Enterprise", + L"WPA-Personal ", + L"WPA2-Personal ", + L"WEP ", + L"UnKnown " +}; + +CHAR16* mSignalStrengthBar[] = { + L"[-----]", + L"[*----]", + L"[**---]", + L"[***--]", + L"[****-]", + L"[*****]" +}; + +#define RSSI_TO_SIGNAL_STRENGTH_BAR(Rssi) mSignalStrengthBar[((Rssi + 19)/20)] + +#define NET_LIST_FOR_EACH_FROM_NODE(Entry, Node, ListHead) \ + for(Entry = Node->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink) + +extern EFI_GUID gWifiConfigFormSetGuid; + +/** + Create Hii Extend Label OpCode as the start opcode and end opcode. + The caller is responsible for freeing the OpCode with HiiFreeOpCodeHandle(). + + @param[in] StartLabelNumber The number of start label. + @param[out] StartOpCodeHandle Points to the start opcode handle. + @param[out] EndOpCodeHandle Points to the end opcode handle. + + @retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this + operation. + @retval EFI_INVALID_PARAMETER Any input parameter is invalid. + @retval EFI_SUCCESS The operation is completed successfully. + @retval Other Errors Returned errors when updating the HII form. + +**/ +EFI_STATUS +WifiMgrCreateOpCode ( + IN UINT16 StartLabelNumber, + OUT VOID **StartOpCodeHandle, + OUT VOID **EndOpCodeHandle + ) +{ + EFI_STATUS Status; + EFI_IFR_GUID_LABEL *InternalStartLabel; + EFI_IFR_GUID_LABEL *InternalEndLabel; + + if (StartOpCodeHandle == NULL || EndOpCodeHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_OUT_OF_RESOURCES; + *StartOpCodeHandle = NULL; + *EndOpCodeHandle = NULL; + + // + // Initialize the container for dynamic opcodes. + // + *StartOpCodeHandle = HiiAllocateOpCodeHandle (); + if (*StartOpCodeHandle == NULL) { + goto Exit; + } + *EndOpCodeHandle = HiiAllocateOpCodeHandle (); + if (*EndOpCodeHandle == NULL) { + goto Exit; + } + + // + // Create Hii Extend Label OpCode as the start opcode. + // + InternalStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + *StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + if (InternalStartLabel == NULL) { + goto Exit; + } + InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + InternalStartLabel->Number = StartLabelNumber; + + // + // Create Hii Extend Label OpCode as the end opcode. + // + InternalEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + *EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + if (InternalEndLabel == NULL) { + goto Exit; + } + InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + InternalEndLabel->Number = LABEL_END; + + return EFI_SUCCESS; + +Exit: + + if (*StartOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (*StartOpCodeHandle); + } + if (*EndOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (*EndOpCodeHandle); + } + return Status; +} + +/** + Display the Nic list contains all available Nics. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_INVALID_PARAMETER Any input parameter is invalid. + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrShowNicList ( + IN WIFI_MGR_PRIVATE_DATA *Private +) +{ + EFI_STATUS Status; + CHAR16 MacString[WIFI_MGR_MAX_MAC_STRING_LEN]; + CHAR16 PortString[WIFI_STR_MAX_SIZE]; + EFI_STRING_ID PortTitleToken; + EFI_STRING_ID PortTitleHelpToken; + WIFI_MGR_DEVICE_DATA *Nic; + LIST_ENTRY *Entry; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + + if (Private == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = WifiMgrCreateOpCode ( + LABEL_MAC_ENTRY, + &StartOpCodeHandle, + &EndOpCodeHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + NET_LIST_FOR_EACH (Entry, &Private->NicList) { + Nic = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_DEVICE_DATA, Link, WIFI_MGR_DEVICE_DATA_SIGNATURE); + WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString); + UnicodeSPrint (PortString, sizeof (PortString), L"MAC %s", MacString); + PortTitleToken = HiiSetString ( + Private->RegisteredHandle, + 0, + PortString, + NULL + ); + if (PortTitleToken == 0) { + Status = EFI_INVALID_PARAMETER; + goto Exit; + } + + UnicodeSPrint (PortString, sizeof (PortString), L"MAC Address"); + PortTitleHelpToken = HiiSetString ( + Private->RegisteredHandle, + 0, + PortString, + NULL + ); + if (PortTitleHelpToken == 0) { + Status = EFI_INVALID_PARAMETER; + goto Exit; + } + + HiiCreateGotoOpCode ( + StartOpCodeHandle, + FORMID_WIFI_MAINPAGE, + PortTitleToken, + PortTitleHelpToken, + EFI_IFR_FLAG_CALLBACK, + (UINT16) (KEY_MAC_ENTRY_BASE + Nic->NicIndex) + ); + } + + Status = HiiUpdateForm ( + Private->RegisteredHandle, // HII handle + &gWifiConfigFormSetGuid, // Formset GUID + FORMID_MAC_SELECTION, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + +Exit: + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + return Status; +} + +/** + Retreive the unicode string of the AKM Suite list of a profile. + The caller is responsible for freeing the string with FreePool(). + + @param[in] Profile The network profile contains a AKM suite list. + + @return the unicode string of AKM suite list or "None". + +**/ +CHAR16* +WifiMgrGetStrAKMList ( + IN WIFI_MGR_NETWORK_PROFILE *Profile +) +{ + UINT8 Index; + UINT16 AKMSuiteCount; + CHAR16 *AKMListDisplay; + + AKMListDisplay = NULL; + if (Profile == NULL || Profile->Network.AKMSuite == NULL) { + goto Exit; + } + + AKMSuiteCount = Profile->Network.AKMSuite->AKMSuiteCount; + if (AKMSuiteCount != 0) { + + // + // Current AKM Suite is between 1-9 + // + AKMListDisplay = (CHAR16 *) AllocateZeroPool(sizeof (CHAR16) * AKMSuiteCount * 2); + if (AKMListDisplay != NULL) { + for (Index = 0; Index < AKMSuiteCount; Index ++) { + UnicodeSPrint ( + AKMListDisplay + (Index * 2), + sizeof (CHAR16) * 2, + L"%d ", + Profile->Network.AKMSuite->AKMSuiteList[Index].SuiteType + ); + if (Index == AKMSuiteCount - 1) { + *(AKMListDisplay + (Index * 2 + 1)) = L'\0'; + } + } + } + } + +Exit: + + if (AKMListDisplay == NULL) { + AKMListDisplay = AllocateCopyPool (sizeof (L"None"), L"None"); + } + return AKMListDisplay; +} + +/** + Retreive the unicode string of the Cipher Suite list of a profile. + The caller is responsible for freeing the string with FreePool(). + + @param[in] Profile The network profile contains a Cipher suite list. + + @return the unicode string of Cipher suite list or "None". + +**/ +CHAR16* +WifiMgrGetStrCipherList ( + IN WIFI_MGR_NETWORK_PROFILE *Profile +) +{ + UINT8 Index; + UINT16 CipherSuiteCount; + CHAR16 *CipherListDisplay; + + CipherListDisplay = NULL; + if (Profile == NULL || Profile->Network.CipherSuite == NULL) { + goto Exit; + } + + CipherSuiteCount = Profile->Network.CipherSuite->CipherSuiteCount; + if (CipherSuiteCount != 0) { + + // + // Current Cipher Suite is between 1-9 + // + CipherListDisplay = (CHAR16 *) AllocateZeroPool(sizeof (CHAR16) * CipherSuiteCount * 2); + if (CipherListDisplay != NULL) { + for (Index = 0; Index < CipherSuiteCount; Index ++) { + UnicodeSPrint ( + CipherListDisplay + (Index * 2), + sizeof (CHAR16) * 2, + L"%d ", + Profile->Network.CipherSuite->CipherSuiteList[Index].SuiteType + ); + if (Index == CipherSuiteCount - 1) { + *(CipherListDisplay + (Index * 2 + 1)) = L'\0'; + } + } + } + } + +Exit: + + if (CipherListDisplay == NULL) { + CipherListDisplay = AllocateCopyPool (sizeof (L"None"), L"None"); + } + return CipherListDisplay; +} + +/** + Refresh the network list display of the current Nic. + + @param[in] Private The pointer to the global private data structure. + @param[out] IfrNvData The IFR NV data. + + @retval EFI_SUCCESS The operation is completed successfully. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Returned errors when creating Opcodes or updating the + Hii form. + +**/ +EFI_STATUS +WifiMgrRefreshNetworkList ( + IN WIFI_MGR_PRIVATE_DATA *Private, + OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + UINT32 AvailableCount; + EFI_STRING_ID PortPromptToken; + EFI_STRING_ID PortTextToken; + EFI_STRING_ID PortHelpToken; + WIFI_MGR_NETWORK_PROFILE *Profile; + LIST_ENTRY *Entry; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + CHAR16 *AKMListDisplay; + CHAR16 *CipherListDisplay; + CHAR16 PortString[WIFI_STR_MAX_SIZE]; + UINTN PortStringSize; + WIFI_MGR_NETWORK_PROFILE *ConnectedProfile; + + if (Private->CurrentNic == NULL) { + return EFI_SUCCESS; + } + + Status = WifiMgrCreateOpCode ( + LABEL_NETWORK_LIST_ENTRY, + &StartOpCodeHandle, + &EndOpCodeHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + AvailableCount = 0; + PortStringSize = sizeof (PortString); + ConnectedProfile = NULL; + AKMListDisplay = NULL; + CipherListDisplay = NULL; + + if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { + + // + // Display the current connected network. + // Find the current operate network under connected status. + // + if (Private->CurrentNic->CurrentOperateNetwork != NULL && + Private->CurrentNic->CurrentOperateNetwork->IsAvailable) { + + Profile = Private->CurrentNic->CurrentOperateNetwork; + AvailableCount ++; + + AKMListDisplay = WifiMgrGetStrAKMList (Profile); + if (AKMListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + CipherListDisplay = WifiMgrGetStrCipherList(Profile); + if (CipherListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + UnicodeSPrint (PortString, PortStringSize, L"%s (Connected)", Profile->SSId); + PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + + if (Profile->SecurityType == SECURITY_TYPE_NONE) { + PortHelpToken = 0; + } else { + UnicodeSPrint (PortString, PortStringSize, L"AKMSuite: %s CipherSuite: %s", AKMListDisplay, CipherListDisplay); + PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + } + FreePool (AKMListDisplay); + FreePool (CipherListDisplay); + AKMListDisplay = NULL; + CipherListDisplay = NULL; + + HiiCreateGotoOpCode ( + StartOpCodeHandle, + FORMID_CONNECT_NETWORK, + PortPromptToken, + PortHelpToken, + EFI_IFR_FLAG_CALLBACK, + (UINT16) (KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) + ); + + UnicodeSPrint ( + PortString, + PortStringSize, + L"%s %s %s", + (Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open "), + mSecurityType[Profile->SecurityType], + RSSI_TO_SIGNAL_STRENGTH_BAR(Profile->NetworkQuality) + ); + PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + + HiiCreateTextOpCode ( + StartOpCodeHandle, + PortTextToken, + 0, + 0 + ); + + ConnectedProfile = Profile; + } else { + Private->CurrentNic->HasDisconnectPendingNetwork = TRUE; + } + } + + // + // Display all supported available networks. + // + NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) { + + Profile = NET_LIST_USER_STRUCT_S ( + Entry, + WIFI_MGR_NETWORK_PROFILE, + Link, + WIFI_MGR_PROFILE_SIGNATURE + ); + if (ConnectedProfile == Profile) { + continue; + } + if (Profile->IsAvailable && Profile->CipherSuiteSupported) { + + AvailableCount ++; + + AKMListDisplay = WifiMgrGetStrAKMList (Profile); + if (AKMListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + CipherListDisplay = WifiMgrGetStrCipherList(Profile); + if (CipherListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL); + if (PortPromptToken == 0) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + if (Profile->SecurityType == SECURITY_TYPE_NONE) { + PortHelpToken = 0; + } else { + UnicodeSPrint ( + PortString, + PortStringSize, + L"AKMSuite: %s CipherSuite: %s", + AKMListDisplay, CipherListDisplay + ); + PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + if (PortHelpToken == 0) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + } + FreePool (AKMListDisplay); + FreePool (CipherListDisplay); + AKMListDisplay = NULL; + CipherListDisplay = NULL; + + HiiCreateGotoOpCode ( + StartOpCodeHandle, + FORMID_CONNECT_NETWORK, + PortPromptToken, + PortHelpToken, + EFI_IFR_FLAG_CALLBACK, + (UINT16) (KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) + ); + + UnicodeSPrint ( + PortString, + PortStringSize, + L"%s %s %s", + (Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open "), + mSecurityType[Profile->SecurityType], + RSSI_TO_SIGNAL_STRENGTH_BAR(Profile->NetworkQuality) + ); + PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + if (PortTextToken == 0) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + HiiCreateTextOpCode ( + StartOpCodeHandle, + PortTextToken, + 0, + 0 + ); + } + } + + // + // Display all Unsupported available networks. + // + NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) { + + Profile = NET_LIST_USER_STRUCT_S ( + Entry, + WIFI_MGR_NETWORK_PROFILE, + Link, + WIFI_MGR_PROFILE_SIGNATURE + ); + if (ConnectedProfile == Profile) { + continue; + } + if (Profile->IsAvailable && !Profile->CipherSuiteSupported) { + + AvailableCount ++; + + AKMListDisplay = WifiMgrGetStrAKMList (Profile); + if (AKMListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + CipherListDisplay = WifiMgrGetStrCipherList(Profile); + if (CipherListDisplay == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL); + + if (Profile->AKMSuiteSupported) { + UnicodeSPrint ( + PortString, + PortStringSize, + L"AKMSuite: %s CipherSuite(UnSupported): %s", + AKMListDisplay, CipherListDisplay + ); + } else { + UnicodeSPrint ( + PortString, + PortStringSize, + L"AKMSuite(UnSupported): %s CipherSuite(UnSupported): %s", + AKMListDisplay, CipherListDisplay + ); + } + FreePool (AKMListDisplay); + FreePool (CipherListDisplay); + AKMListDisplay = NULL; + CipherListDisplay = NULL; + + PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + + HiiCreateGotoOpCode ( + StartOpCodeHandle, + FORMID_CONNECT_NETWORK, + PortPromptToken, + PortHelpToken, + EFI_IFR_FLAG_CALLBACK, + (UINT16) (KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) + ); + + UnicodeSPrint ( + PortString, + PortStringSize, + L"%s %s %s", + L"UnSupported", + mSecurityType[Profile->SecurityType], + RSSI_TO_SIGNAL_STRENGTH_BAR(Profile->NetworkQuality) + ); + PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); + + HiiCreateTextOpCode ( + StartOpCodeHandle, + PortTextToken, + 0, + 0 + ); + } + } + + Status = HiiUpdateForm ( + Private->RegisteredHandle, // HII handle + &gWifiConfigFormSetGuid, // Formset GUID + FORMID_NETWORK_LIST, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + +Exit: + + gBS->RestoreTPL (OldTpl); + + if (AKMListDisplay != NULL) { + FreePool (AKMListDisplay); + } + if (CipherListDisplay != NULL) { + FreePool (CipherListDisplay); + } + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Network List is Refreshed!\n")); + return Status; +} + +/** + Refresh the hidden network list configured by user. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_SUCCESS The operation is completed successfully. + @retval Other Errors Returned errors when creating Opcodes or updating the + Hii form. +**/ +EFI_STATUS +WifiMgrRefreshHiddenList ( + IN WIFI_MGR_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + UINTN Index; + EFI_STRING_ID StringId; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + LIST_ENTRY *Entry; + + if (Private == NULL) { + return EFI_SUCCESS; + } + + Status = WifiMgrCreateOpCode ( + LABEL_HIDDEN_NETWORK_ENTRY, + &StartOpCodeHandle, + &EndOpCodeHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Index = 0; + + NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S ( + Entry, + WIFI_HIDDEN_NETWORK_DATA, + Link, + WIFI_MGR_HIDDEN_NETWORK_SIGNATURE + ); + StringId = HiiSetString (Private->RegisteredHandle, 0, HiddenNetwork->SSId, NULL); + + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, + (EFI_QUESTION_ID) (KEY_HIDDEN_NETWORK_ENTRY_BASE + Index), + MANAGER_VARSTORE_ID, + (UINT16) (HIDDEN_NETWORK_LIST_VAR_OFFSET + Index), + StringId, + 0, + 0, + 0, + NULL + ); + Index ++; + } + + Status = HiiUpdateForm ( + Private->RegisteredHandle, // HII handle + &gWifiConfigFormSetGuid, // Formset GUID + FORMID_HIDDEN_NETWORK_LIST, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + gBS->RestoreTPL (OldTpl); + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + return Status; +} + + +/** + Callback function for user to select a Nic. + + @param[in] Private The pointer to the global private data structure. + @param[in] KeyValue The key value received from HII input. + + @retval EFI_NOT_FOUND The corresponding Nic is not found. + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrSelectNic ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_QUESTION_ID KeyValue + ) +{ + WIFI_MGR_DEVICE_DATA *Nic; + UINT32 NicIndex; + CHAR16 MacString[WIFI_MGR_MAX_MAC_STRING_LEN]; + + NicIndex = KeyValue - KEY_MAC_ENTRY_BASE; + Nic = WifiMgrGetNicByIndex (Private, NicIndex); + if (Nic == NULL) { + return EFI_NOT_FOUND; + } + Private->CurrentNic = Nic; + + WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN(STR_MAC_ADDRESS), MacString, NULL); + return EFI_SUCCESS; +} + +/** + Restore the NV data to be default. + + @param[in] Private The pointer to the global private data structure. + @param[out] IfrNvData The IFR NV data. + +**/ +VOID +WifiMgrCleanUserInput ( + IN WIFI_MGR_PRIVATE_DATA *Private + ) +{ + Private->SecurityType = SECURITY_TYPE_NONE; + Private->EapAuthMethod = EAP_AUTH_METHOD_TTLS; + Private->EapSecondAuthMethod = EAP_SEAUTH_METHOD_MSCHAPV2; + Private->FileType = FileTypeMax; +} + +/** + UI handle function when user select a network to connect. + + @param[in] Private The pointer to the global private data structure. + @param[in] ProfileIndex The profile index user selected to connect. + + @retval EFI_INVALID_PARAMETER Nic is null. + @retval EFI_NOT_FOUND Profile could not be found. + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrUserSelectProfileToConnect( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN UINT32 ProfileIndex + ) +{ + WIFI_MGR_NETWORK_PROFILE *Profile; + WIFI_MGR_DEVICE_DATA *Nic; + + Nic = Private->CurrentNic; + if (Nic == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + //Initialize the connection page + // + WifiMgrCleanUserInput(Private); + + Profile = WifiMgrGetProfileByProfileIndex (ProfileIndex, &Nic->ProfileList); + if (Profile == NULL) { + return EFI_NOT_FOUND; + } + Private->CurrentNic->UserSelectedProfile = Profile; + + return EFI_SUCCESS; +} + +/** + Record password from a HII input string. + + @param[in] Private The pointer to the global private data structure. + @param[in] StringId The QuestionId received from HII input. + @param[in] StringBuffer The unicode string buffer to store password. + @param[in] StringBufferLen The len of unicode string buffer. + + @retval EFI_INVALID_PARAMETER Any input parameter is invalid. + @retval EFI_NOT_FOUND The password string is not found or invalid. + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrRecordPassword ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN EFI_STRING_ID StringId, + IN CHAR16 *StringBuffer, + IN UINTN StringBufferLen + ) +{ + CHAR16 *Password; + + if (StringId == 0 || StringBuffer == NULL || StringBufferLen <= 0) { + return EFI_INVALID_PARAMETER; + } + + Password = HiiGetString (Private->RegisteredHandle, StringId, NULL); + if (Password == NULL) { + return EFI_NOT_FOUND; + } + if (StrLen (Password) > StringBufferLen) { + FreePool (Password); + return EFI_NOT_FOUND; + } + StrnCpyS (StringBuffer, StringBufferLen, Password, StrLen (Password)); + ZeroMem (Password, (StrLen (Password) + 1) * sizeof (CHAR16)); + FreePool (Password); + + // + // Clean password in string package + // + HiiSetString (Private->RegisteredHandle, StringId, L"", NULL); + return EFI_SUCCESS; +} + +/** + Update connection message on connect configuration page, and trigger related form refresh. + + @param[in] Nic The related Nic for updating message. + @param[in] ConnectStateChanged The tag to tell if the connection state has been changed, only + when the connection changes from "Connected" or "Disconnecting" + to "Disconnected", or from "Disconnected" or "Connecting" to + "Connected", this tag can be set as TRUE. + @param[in] ConnectStatusMessage The message to show on connected status bar, if NULL, will + use default message. + +**/ +VOID +WifiMgrUpdateConnectMessage ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN BOOLEAN ConnectStateChanged, + IN EFI_STRING ConnectStatusMessage + ) +{ + CHAR16 ConnectStatusStr[WIFI_STR_MAX_SIZE]; + WIFI_MGR_PRIVATE_DATA *Private; + + Private = Nic->Private; + if (Private == NULL || Private->CurrentNic != Nic) { + return; + } + + // + // Update Connection Status Bar + // + if (ConnectStatusMessage != NULL) { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusMessage, NULL); + } else { + if (Nic->ConnectState == WifiMgrConnectedToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Connected to %s", + Nic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else if (Nic->ConnectState == WifiMgrDisconnected) { + + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), L"Disconnected", NULL); + } else if (Nic->ConnectState == WifiMgrConnectingToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Connecting to %s ...", + Nic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else if (Nic->ConnectState == WifiMgrDisconnectingToAp) { + + UnicodeSPrint (ConnectStatusStr, sizeof (ConnectStatusStr), L"Disconnecting from %s ...", + Nic->CurrentOperateNetwork->SSId); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); + } else { + return; + } + } + + // + // Update Connect Button + // + if (Nic->ConnectState == WifiMgrConnectedToAp && Nic->UserSelectedProfile == Nic->CurrentOperateNetwork) { + + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_CONNECT_NOW), L"Disconnect from this Network", NULL); + } else { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_NOW), L"Connect to this Network", NULL); + } + gBS->SignalEvent (Private->ConnectFormRefreshEvent); + + // + // Update Main Page and Network List + // + if (ConnectStateChanged) { + + if (Nic->ConnectState == WifiMgrConnectedToAp) { + + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Connected to", NULL); + HiiSetString (Private->RegisteredHandle, + STRING_TOKEN (STR_CONNECTED_SSID), Nic->CurrentOperateNetwork->SSId, NULL); + } else { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Disconnected", NULL); + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTED_SSID), L"", NULL); + } + + gBS->SignalEvent (Private->NetworkListRefreshEvent); + gBS->SignalEvent (Private->MainPageRefreshEvent); + } +} + +/** + Convert the driver configuration data into the IFR data. + + @param[in] Private The pointer to the global private data structure. + @param[out] IfrNvData The IFR NV data. + + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrConvertConfigDataToIfrNvData ( + IN WIFI_MGR_PRIVATE_DATA *Private, + OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData + ) +{ + // + // Private shouldn't be NULL here, assert if Private is NULL. + // + ASSERT (Private != NULL); + + if (Private->CurrentNic != NULL) { + IfrNvData->ProfileCount = Private->CurrentNic->AvailableCount; + } else { + IfrNvData->ProfileCount = 0; + } + + return EFI_SUCCESS; +} + +/** + Convert the IFR data into the driver configuration data. + + @param[in] Private The pointer to the global private data structure. + @param[in, out] IfrNvData The IFR NV data. + + @retval EFI_SUCCESS The operation is completed successfully. + +**/ +EFI_STATUS +WifiMgrConvertIfrNvDataToConfigData ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData + ) +{ + return EFI_SUCCESS; +} + +/** + This function allows the caller to request the current + configuration for one or more named elements. The resulting + string is in <ConfigAltResp> format. Any and all alternative + configuration strings shall also be appended to the end of the + current configuration string. If they are, they must appear + after the current configuration. They must contain the same + routing (GUID, NAME, PATH) as the current configuration string. + They must have an additional description indicating the type of + alternative configuration the string represents, + "ALTCFG=<StringToken>". That <StringToken> (when + converted from Hex UNICODE to binary) is a reference to a + string in the associated string pack. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Request A null-terminated Unicode string in + <ConfigRequest> format. Note that this + includes the routing information as well as + the configurable name / value pairs. It is + invalid for this string to be in + <MultiConfigRequest> format. + If a NULL is passed in for the Request field, + all of the settings being abstracted by this function + will be returned in the Results field. In addition, + if a ConfigHdr is passed in with no request elements, + all of the settings being abstracted for that particular + ConfigHdr reference will be returned in the Results Field. + + @param Progress On return, points to a character in the + Request string. Points to the string's null + terminator if request was successful. Points + to the most recent "&" before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair) if the request was not + successful. + + @param Results A null-terminated Unicode string in + <MultiConfigAltResp> format which has all values + filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_NOT_FOUND Routing data doesn't match any + known driver. Progress set to the + first character in the routing header. + Note: There is no requirement that the + driver validate the routing data. It + must skip the <ConfigHdr> in order to + process the names. + + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set + to most recent "&" before the + error or the beginning of the + string. + + @retval EFI_INVALID_PARAMETER Unknown name. Progress points + to the & before the name in + question. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + WIFI_MGR_PRIVATE_DATA *Private; + WIFI_MANAGER_IFR_NVDATA *IfrNvData; + EFI_STRING ConfigRequestHdr; + EFI_STRING ConfigRequest; + UINTN Size; + BOOLEAN AllocatedRequest; + UINTN BufferSize; + EFI_STATUS Status; + + if (This == NULL || Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + + *Progress = Request; + if ((Request != NULL) && + !HiiIsConfigHdrMatch (Request, &gWifiConfigFormSetGuid, mVendorStorageName)) { + return EFI_NOT_FOUND; + } + + ConfigRequestHdr = NULL; + ConfigRequest = NULL; + AllocatedRequest = FALSE; + Size = 0; + + Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); + + BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); + IfrNvData = AllocateZeroPool (BufferSize); + if (IfrNvData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData); + + ConfigRequest = Request; + if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { + // + // Request has no request element, construct full request string. + // Allocate and fill a buffer large enough to hold the <ConfigHdr> template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator. + // + ConfigRequestHdr = HiiConstructConfigHdr ( + &gWifiConfigFormSetGuid, + mVendorStorageName, + Private->DriverHandle); + if (ConfigRequestHdr == NULL) { + FreePool (IfrNvData); + return EFI_OUT_OF_RESOURCES; + } + + Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + if (ConfigRequest == NULL) { + + FreePool (IfrNvData); + FreePool (ConfigRequestHdr); + return EFI_OUT_OF_RESOURCES; + } + + AllocatedRequest = TRUE; + UnicodeSPrint ( + ConfigRequest, + Size, + L"%s&OFFSET=0&WIDTH=%016LX", + ConfigRequestHdr, + (UINT64) BufferSize + ); + FreePool (ConfigRequestHdr); + } + + // + // Convert buffer data to <ConfigResp> by helper function BlockToConfig() + // + Status = gHiiConfigRouting->BlockToConfig ( + gHiiConfigRouting, + ConfigRequest, + (UINT8 *) IfrNvData, + BufferSize, + Results, + Progress + ); + + FreePool (IfrNvData); + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + ConfigRequest = NULL; + } + // + // Set Progress string to the original request string. + // + if (Request == NULL) { + *Progress = NULL; + } else if (StrStr (Request, L"OFFSET") == NULL) { + *Progress = Request + StrLen (Request); + } + + return Status; +} + +/** + This function applies changes in a driver's configuration. + Input is a Configuration, which has the routing data for this + driver followed by name / value configuration pairs. The driver + must apply those pairs to its configurable storage. If the + driver's configuration is stored in a linear block of data + and the driver's name / value pairs are in <BlockConfig> + format, it may use the ConfigToBlock helper function (above) to + simplify the job. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Configuration A null-terminated Unicode string in + <ConfigString> format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginn ing of the string if the failure + is in the first name / value pair) or + the terminating NULL if all was + successful. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + Results parameter would result + in this type of error. + + @retval EFI_NOT_FOUND Target for the specified routing data + was not found + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + WIFI_MGR_PRIVATE_DATA *Private; + WIFI_MANAGER_IFR_NVDATA *IfrNvData; + + if (Configuration == NULL || Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + + IfrNvData = NULL; + *Progress = Configuration; + BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); + Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); + + if (!HiiIsConfigHdrMatch (Configuration, &gWifiConfigFormSetGuid, mVendorStorageName)) { + return EFI_NOT_FOUND; + } + + IfrNvData = AllocateZeroPool (BufferSize); + if (IfrNvData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData); + + Status = gHiiConfigRouting->ConfigToBlock ( + gHiiConfigRouting, + Configuration, + (UINT8*) IfrNvData, + &BufferSize, + Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = WifiMgrConvertIfrNvDataToConfigData (Private, IfrNvData); + ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA)); + FreePool (IfrNvData); + + return Status; +} + +/** + This function is called to provide results data to the driver. + This data consists of a unique key that is used to identify + which data is either being passed back or being asked for. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. The format of the data tends to + vary based on the opcode that generated the callback. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + UINTN BufferSize; + WIFI_MGR_PRIVATE_DATA *Private; + WIFI_MANAGER_IFR_NVDATA *IfrNvData; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + WIFI_MGR_NETWORK_PROFILE *Profile; + WIFI_MGR_NETWORK_PROFILE *ProfileToConnect; + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + UINTN TempDataSize; + VOID *TempData; + LIST_ENTRY *Entry; + UINT32 Index; + UINT32 RemoveCount; + CHAR16 *TempPassword; + CHAR16 *ErrorMessage; + + if (Action != EFI_BROWSER_ACTION_FORM_OPEN && + Action != EFI_BROWSER_ACTION_FORM_CLOSE && + Action != EFI_BROWSER_ACTION_CHANGING && + Action != EFI_BROWSER_ACTION_CHANGED && + Action != EFI_BROWSER_ACTION_RETRIEVE) { + + return EFI_UNSUPPORTED; + } + if ((Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_SUCCESS; + Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); + if (Private->CurrentNic == NULL) { + return EFI_DEVICE_ERROR; + } + + // + // Retrieve uncommitted data from Browser + // + BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); + IfrNvData = AllocateZeroPool (BufferSize); + if (IfrNvData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + HiiGetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *) IfrNvData); + + if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { + switch (QuestionId) { + + case KEY_MAC_LIST: + + Status = WifiMgrShowNicList (Private); + break; + + case KEY_REFRESH_NETWORK_LIST: + + if (Private->CurrentNic->UserSelectedProfile != NULL) { + + Profile = Private->CurrentNic->UserSelectedProfile; + + // + // Erase secrets since user has left Connection Page + // Connection Page may direct to Network List Page or Eap Configuration Page, + // secrets only need to be erased when head to Network List Page + // + WifiMgrCleanProfileSecrets (Profile); + + Private->CurrentNic->UserSelectedProfile = NULL; + } + + break; + + case KEY_CONNECT_ACTION: + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + // + //Enter the network connection configuration page + //Recovery from restored data + // + if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) { + return EFI_OUT_OF_RESOURCES; + } + IfrNvData->SecurityType = Profile->SecurityType; + if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SECURITY_TYPE), + mSecurityType[IfrNvData->SecurityType], NULL) == 0) { + return EFI_OUT_OF_RESOURCES; + } + + if (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) { + + IfrNvData->EapAuthMethod = Profile->EapAuthMethod; + IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod; + StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity); + } + + break; + + case KEY_ENROLLED_CERT_NAME: + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + // + //Enter the key enrollment page + //For TTLS and PEAP, only CA cert needs to be cared + // + if (Private->FileType == FileTypeCACert) { + + if (Profile->CACertData != NULL) { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->CACertName, NULL); + } else { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); + } + } else if (Private->FileType == FileTypeClientCert) { + + if (Profile->ClientCertData != NULL) { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->ClientCertName, NULL); + } else { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); + } + } + break; + + case KEY_ENROLLED_PRIVATE_KEY_NAME: + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + if (Profile->PrivateKeyData != NULL) { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), Profile->PrivateKeyName, NULL); + } else { + HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL); + } + break; + + default: + break; + } + } else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { + switch (QuestionId) { + + case KEY_CONNECT_ACTION: + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + // + //Restore User Config Data for Page recovery + // + if (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) { + + Profile->EapAuthMethod = IfrNvData->EapAuthMethod; + Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod; + StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity); + } + break; + + default: + break; + } + } else if (Action == EFI_BROWSER_ACTION_CHANGING) { + switch (QuestionId) { + + case KEY_NETWORK_LIST: + + // + //User triggered a scan process. + // + Private->CurrentNic->OneTimeScanRequest = TRUE; + break; + + case KEY_PASSWORD_CONNECT_NETWORK: + case KEY_EAP_PASSWORD_CONNECT_NETWORK: + case KEY_PRIVATE_KEY_PASSWORD: + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + if (QuestionId == KEY_PASSWORD_CONNECT_NETWORK) { + TempPassword = Profile->Password; + } else if (QuestionId == KEY_EAP_PASSWORD_CONNECT_NETWORK) { + TempPassword = Profile->EapPassword; + } else { + TempPassword = Profile->PrivateKeyPassword; + } + + Status = WifiMgrRecordPassword (Private, Value->string, TempPassword, PASSWORD_STORAGE_SIZE); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: Failed to input password!")); + break; + } + + // + // This password is not a new created password, so no need to confirm. + // + Status = EFI_NOT_FOUND; + break; + + case KEY_CONNECT_ACTION: + + ErrorMessage = NULL; + ProfileToConnect = NULL; + + if (Private->CurrentNic->UserSelectedProfile == NULL) { + break; + } + Profile = Private->CurrentNic->UserSelectedProfile; + + if (Private->CurrentNic->ConnectState == WifiMgrDisconnected || + Profile != Private->CurrentNic->CurrentOperateNetwork) { + + // + // When this network is not currently connected, pend it to connect. + // + if (Profile->AKMSuiteSupported && Profile->CipherSuiteSupported) { + + if (Profile->SecurityType == SECURITY_TYPE_NONE || Profile->SecurityType == SECURITY_TYPE_WPA2_PERSONAL) { + + // + // For Open network, connect directly. + // + ProfileToConnect = Profile; + + } else if (Profile->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) { + + // + // For WPA/WPA2-Enterprise network, conduct eap configuration first. + // Only EAP-TLS, TTLS and PEAP is supported now! + // + Profile->EapAuthMethod = IfrNvData->EapAuthMethod; + StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity); + + if (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TTLS || IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_PEAP) { + + Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod; + ProfileToConnect = Profile; + } else if (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TLS) { + ProfileToConnect = Profile; + } else { + ErrorMessage = L"ERROR: Only EAP-TLS, TTLS or PEAP is supported now!"; + } + } else { + ErrorMessage = L"ERROR: Can't connect to this network!"; + } + } else { + ErrorMessage = L"ERROR: This network is not supported!"; + } + + if (ErrorMessage != NULL) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + ErrorMessage, + NULL + ); + } + + if (ProfileToConnect != NULL) { + + Private->CurrentNic->OneTimeConnectRequest = TRUE; + Private->CurrentNic->ConnectPendingNetwork = ProfileToConnect; + } + } else if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { + + // + // This network is currently connected, just disconnect from it. + // + Private->CurrentNic->OneTimeDisconnectRequest = TRUE; + Private->CurrentNic->HasDisconnectPendingNetwork = TRUE; + } + break; + + case KEY_ENROLL_CA_CERT_CONNECT_NETWORK: + + Private->FileType = FileTypeCACert; + break; + + case KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK: + + Private->FileType = FileTypeClientCert; + break; + + case KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE: + + FilePath = NULL; + ChooseFile (NULL, NULL, NULL, &FilePath); + + if (FilePath != NULL) { + + UpdatePrivateKeyFromFile(Private, FilePath); + FreePool (FilePath); + } + break; + + case KEY_EAP_ENROLL_CERT_FROM_FILE: + + // + //User will select a cert file from File Explore + // + FilePath = NULL; + ChooseFile( NULL, NULL, NULL, &FilePath); + + if (FilePath != NULL) { + + UpdateCAFromFile(Private, FilePath); + FreePool (FilePath); + } + break; + + case KEY_SAVE_PRIVATE_KEY_TO_MEM: + + if (Private->FileContext != NULL && Private->FileContext->FHandle != NULL && + Private->CurrentNic->UserSelectedProfile != NULL) { + + // + // Read Private Key file to Buffer + // + Profile = Private->CurrentNic->UserSelectedProfile; + if (Profile->PrivateKeyData != NULL) { + + ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize); + FreePool (Profile->PrivateKeyData); + Profile->PrivateKeyData = NULL; + } + + Status = WifiMgrReadFileToBuffer ( + Private->FileContext, + &TempData, + &TempDataSize + ); + if (EFI_ERROR (Status)) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"ERROR: Can't read this private key file!", + NULL + ); + } else { + + ASSERT (Private->FileContext->FileName != NULL); + + Profile->PrivateKeyData = TempData; + Profile->PrivateKeyDataSize = TempDataSize; + StrCpyS(Profile->PrivateKeyName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Private Key: %s has been enrolled! Size: %d\n", + Profile->PrivateKeyName, Profile->PrivateKeyDataSize)); + } + } + break; + + case KEY_SAVE_CERT_TO_MEM: + + if (Private->FileContext != NULL && Private->FileContext->FHandle != NULL && + Private->CurrentNic->UserSelectedProfile != NULL) { + + // + // Read Cert file to Buffer + // + Profile = Private->CurrentNic->UserSelectedProfile; + + if (Private->FileType == FileTypeCACert) { + if (Profile->CACertData != NULL) { + + ZeroMem (Profile->CACertData, Profile->CACertSize); + FreePool (Profile->CACertData); + Profile->CACertData = NULL; + } + } else if (Private->FileType == FileTypeClientCert) { + if (Profile->ClientCertData != NULL) { + + ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); + FreePool (Profile->ClientCertData); + Profile->ClientCertData = NULL; + } + } else { + break; + } + + Status = WifiMgrReadFileToBuffer ( + Private->FileContext, + &TempData, + &TempDataSize + ); + if (EFI_ERROR (Status)) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"ERROR: Can't read this certificate file!", + NULL + ); + } else { + + ASSERT (Private->FileContext->FileName != NULL); + if (Private->FileType == FileTypeCACert) { + + Profile->CACertData = TempData; + Profile->CACertSize = TempDataSize; + StrCpyS(Profile->CACertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] CA Cert: %s has been enrolled! Size: %d\n", + Profile->CACertName, Profile->CACertSize)); + } else { + + Profile->ClientCertData = TempData; + Profile->ClientCertSize = TempDataSize; + StrCpyS(Profile->ClientCertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Client Cert: %s has been enrolled! Size: %d\n", + Profile->ClientCertName, Profile->ClientCertSize)); + } + } + } + break; + + case KEY_ADD_HIDDEN_NETWORK: + + // + // Add a Hidden Network + // + if (StrLen (IfrNvData->SSId) < SSID_MIN_LEN || + Private->HiddenNetworkCount >= HIDDEN_NETWORK_LIST_COUNT_MAX) { + + Status = EFI_ABORTED; + break; + } else { + + // + // Check if this SSId is already in Hidden Network List + // + NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, + Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + if (StrCmp (HiddenNetwork->SSId, IfrNvData->SSId) == 0) { + + Status = EFI_ABORTED; + break; + } + } + } + + HiddenNetwork = (WIFI_HIDDEN_NETWORK_DATA *) AllocateZeroPool (sizeof (WIFI_HIDDEN_NETWORK_DATA)); + if (HiddenNetwork == NULL) { + + Status = EFI_OUT_OF_RESOURCES; + break; + } + HiddenNetwork->Signature = WIFI_MGR_HIDDEN_NETWORK_SIGNATURE; + StrCpyS (HiddenNetwork->SSId, SSID_STORAGE_SIZE, IfrNvData->SSId); + + InsertTailList (&Private->HiddenNetworkList, &HiddenNetwork->Link); + Private->HiddenNetworkCount ++; + + WifiMgrRefreshHiddenList (Private); + break; + + case KEY_REMOVE_HIDDEN_NETWORK: + + // + // Remove Hidden Networks + // + Entry = GetFirstNode (&Private->HiddenNetworkList); + RemoveCount = 0; + for (Index = 0; Index < Private->HiddenNetworkCount; Index ++) { + if (IfrNvData->HiddenNetworkList[Index] != 0) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + Entry = RemoveEntryList (Entry); + RemoveCount ++; + + FreePool (HiddenNetwork); + } else { + Entry = GetNextNode (&Private->HiddenNetworkList, Entry); + } + } + + Private->HiddenNetworkCount -= RemoveCount; + WifiMgrRefreshHiddenList (Private); + break; + + default: + + if (QuestionId >= KEY_MAC_ENTRY_BASE && QuestionId < KEY_MAC_ENTRY_BASE + Private->NicCount) { + // + // User selects a wireless NIC. + // + Status = WifiMgrSelectNic (Private, QuestionId); + if (EFI_ERROR (Status)) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"ERROR: Fail to operate the wireless NIC!", + NULL + ); + } + } else if (Private->CurrentNic != NULL) { + if (QuestionId >= KEY_AVAILABLE_NETWORK_ENTRY_BASE && + QuestionId <= KEY_AVAILABLE_NETWORK_ENTRY_BASE + Private->CurrentNic->MaxProfileIndex) { + + Status = WifiMgrUserSelectProfileToConnect (Private, QuestionId - KEY_AVAILABLE_NETWORK_ENTRY_BASE); + if (!EFI_ERROR (Status)) { + WifiMgrUpdateConnectMessage(Private->CurrentNic, FALSE, NULL); + } + } + + if (EFI_ERROR (Status)) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"ERROR: Fail to operate this profile!", + NULL + ); + } + } + + break; + } + } else if (Action == EFI_BROWSER_ACTION_CHANGED) { + switch (QuestionId) { + + case KEY_SAVE_CERT_TO_MEM: + case KEY_SAVE_PRIVATE_KEY_TO_MEM: + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; + break; + + case KEY_NO_SAVE_CERT_TO_MEM: + case KEY_NO_SAVE_PRIVATE_KEY_TO_MEM: + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; + break; + + default: + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + break; + } + } else if (Action == EFI_BROWSER_ACTION_RETRIEVE) { + + switch (QuestionId) { + + case KEY_REFRESH_NETWORK_LIST: + + WifiMgrRefreshNetworkList (Private, IfrNvData); + break; + + default: + break; + } + } + + if (!EFI_ERROR (Status)) { + // + // Pass changed uncommitted data back to Form Browser. + // + BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); + HiiSetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *) IfrNvData, NULL); + } + + ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA)); + FreePool (IfrNvData); + return Status; +} + +/** + Initialize the WiFi configuration form. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_SUCCESS The configuration form is initialized. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_INVALID_PARAMETER Any input parameter is invalid. + @retval Other Erros Returned Errors when installing protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormInit ( + WIFI_MGR_PRIVATE_DATA *Private +) +{ + EFI_STATUS Status; + + if (Private == NULL) { + return EFI_INVALID_PARAMETER; + } + + Private->ConfigAccess.ExtractConfig = WifiMgrDxeHiiConfigAccessExtractConfig; + Private->ConfigAccess.RouteConfig = WifiMgrDxeHiiConfigAccessRouteConfig; + Private->ConfigAccess.Callback = WifiMgrDxeHiiConfigAccessCallback; + + // + // Install Device Path Protocol and Config Access protocol to driver handle. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mWifiMgrDxeHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &Private->ConfigAccess, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Publish our HII data. + // + Private->RegisteredHandle = HiiAddPackages ( + &gWifiConfigFormSetGuid, + Private->DriverHandle, + WifiConnectionManagerDxeStrings, + WifiConnectionManagerDxeBin, + NULL + ); + if (Private->RegisteredHandle == NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + Private->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mWifiMgrDxeHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &Private->ConfigAccess, + NULL + ); + return EFI_OUT_OF_RESOURCES; + } + + Private->FileContext = AllocateZeroPool (sizeof (WIFI_MGR_FILE_CONTEXT)); + if (Private->FileContext == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + return EFI_SUCCESS; +} + +/** + Unload the WiFi configuration form. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_SUCCESS The configuration form is unloaded successfully. + @retval EFI_INVALID_PARAMETER Any input parameter is invalid. + @retval Other Errors Returned Erros when uninstalling protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormUnload ( + WIFI_MGR_PRIVATE_DATA *Private +) +{ + EFI_STATUS Status; + + if (Private == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Private->FileContext != NULL) { + + if (Private->FileContext->FHandle != NULL) { + Private->FileContext->FHandle->Close (Private->FileContext->FHandle); + } + + if (Private->FileContext->FileName != NULL) { + FreePool (Private->FileContext->FileName); + } + FreePool (Private->FileContext); + } + + HiiRemovePackages(Private->RegisteredHandle); + + Status = gBS->UninstallMultipleProtocolInterfaces ( + Private->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mWifiMgrDxeHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &Private->ConfigAccess, + NULL + ); + + return Status; +} diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h new file mode 100644 index 00000000..3d249f32 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.h @@ -0,0 +1,241 @@ +/** @file + The Hii functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_MGR_HII_CONFIG_ACCESS__ +#define __EFI_WIFI_MGR_HII_CONFIG_ACCESS__ + +/** + Update connection message on connect configuration page, and trigger related form refresh. + + @param[in] Nic The related Nic for updating message. + @param[in] ConnectStateChanged The tag to tell if the connection state has been changed, only + when the connection changes from "Connected" or "Disconnecting" + to "Disconnected", or from "Disconnected" or "Connecting" to + "Connected", this tag can be set as TRUE. + @param[in] ConnectStatusMessage The message to show on connected status bar, if NULL, will + use default message. + +**/ +VOID +WifiMgrUpdateConnectMessage ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN BOOLEAN ConnectStateChanged, + IN EFI_STRING ConnectStatusMessage + ); + +/** + This function allows the caller to request the current + configuration for one or more named elements. The resulting + string is in <ConfigAltResp> format. Any and all alternative + configuration strings shall also be appended to the end of the + current configuration string. If they are, they must appear + after the current configuration. They must contain the same + routing (GUID, NAME, PATH) as the current configuration string. + They must have an additional description indicating the type of + alternative configuration the string represents, + "ALTCFG=<StringToken>". That <StringToken> (when + converted from Hex UNICODE to binary) is a reference to a + string in the associated string pack. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Request A null-terminated Unicode string in + <ConfigRequest> format. Note that this + includes the routing information as well as + the configurable name / value pairs. It is + invalid for this string to be in + <MultiConfigRequest> format. + If a NULL is passed in for the Request field, + all of the settings being abstracted by this function + will be returned in the Results field. In addition, + if a ConfigHdr is passed in with no request elements, + all of the settings being abstracted for that particular + ConfigHdr reference will be returned in the Results Field. + + @param Progress On return, points to a character in the + Request string. Points to the string's null + terminator if request was successful. Points + to the most recent "&" before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair) if the request was not + successful. + + @param Results A null-terminated Unicode string in + <MultiConfigAltResp> format which has all values + filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_NOT_FOUND Routing data doesn't match any + known driver. Progress set to the + first character in the routing header. + Note: There is no requirement that the + driver validate the routing data. It + must skip the <ConfigHdr> in order to + process the names. + + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set + to most recent "&" before the + error or the beginning of the + string. + + @retval EFI_INVALID_PARAMETER Unknown name. Progress points + to the & before the name in + question. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ); + +/** + This function applies changes in a driver's configuration. + Input is a Configuration, which has the routing data for this + driver followed by name / value configuration pairs. The driver + must apply those pairs to its configurable storage. If the + driver's configuration is stored in a linear block of data + and the driver's name / value pairs are in <BlockConfig> + format, it may use the ConfigToBlock helper function (above) to + simplify the job. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Configuration A null-terminated Unicode string in + <ConfigString> format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginn ing of the string if the failure + is in the first name / value pair) or + the terminating NULL if all was + successful. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + Results parameter would result + in this type of error. + + @retval EFI_NOT_FOUND Target for the specified routing data + was not found + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ); + +/** + This function is called to provide results data to the driver. + This data consists of a unique key that is used to identify + which data is either being passed back or being asked for. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. The format of the data tends to + vary based on the opcode that generated the callback. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. + +**/ +EFI_STATUS +EFIAPI +WifiMgrDxeHiiConfigAccessCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ); + +/** + Initialize the WiFi configuration form. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_SUCCESS The configuration form is initialized. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Erros Returned errors when installing protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormInit ( + WIFI_MGR_PRIVATE_DATA *Private + ); + +/** + Unload the WiFi configuration form. + + @param[in] Private The pointer to the global private data structure. + + @retval EFI_SUCCESS The configuration form is unloaded successfully. + @retval Other Errors Returned Erros when uninstalling protocols. + +**/ +EFI_STATUS +WifiMgrDxeConfigFormUnload ( + WIFI_MGR_PRIVATE_DATA *Private + ); + +/** + Refresh the network list display of the current Nic. + + @param[in] Private The pointer to the global private data structure. + @param[out] IfrNvData The IFR NV data. + + @retval EFI_SUCCESS The operation is completed successfully. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Returned errors when creating Opcodes or updating the + Hii form. + +**/ +EFI_STATUS +WifiMgrRefreshNetworkList ( + IN WIFI_MGR_PRIVATE_DATA *Private, + OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c new file mode 100644 index 00000000..a326ff16 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.c @@ -0,0 +1,1285 @@ +/** @file + The Mac Connection2 Protocol adapter functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrDxe.h" + +EFI_EAP_TYPE mEapAuthMethod[] = { + EFI_EAP_TYPE_TTLS, + EFI_EAP_TYPE_PEAP, + EFI_EAP_TYPE_EAPTLS +}; + +EFI_EAP_TYPE mEapSecondAuthMethod[] = { + EFI_EAP_TYPE_MSCHAPV2 +}; + +/** + The callback function for scan operation. This function updates networks + according to the latest scan result, and trigger UI refresh. + + ASSERT when errors occur in config token. + + @param[in] Event The GetNetworks token receive event. + @param[in] Context The context of the GetNetworks token. + +**/ +VOID +EFIAPI +WifiMgrOnScanFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + WIFI_MGR_DEVICE_DATA *Nic; + WIFI_MGR_NETWORK_PROFILE *Profile; + EFI_80211_NETWORK *Network; + UINTN DataSize; + EFI_80211_NETWORK_DESCRIPTION *NetworkDescription; + EFI_80211_GET_NETWORKS_RESULT *Result; + LIST_ENTRY *Entry; + UINT8 SecurityType; + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + CHAR8 *AsciiSSId; + UINTN Index; + + ASSERT (Context != NULL); + + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN *) Context; + ASSERT (ConfigToken->Nic != NULL); + ASSERT (ConfigToken->Type == TokenTypeGetNetworksToken); + + // + // It is the GetNetworks token, set scan state to "ScanFinished" + // + ConfigToken->Nic->ScanState = WifiMgrScanFinished; + + ASSERT (ConfigToken->Token.GetNetworksToken != NULL); + Result = ConfigToken->Token.GetNetworksToken->Result; + Nic = ConfigToken->Nic; + + // + // Clean previous result, and update network list according to the scan result + // + Nic->AvailableCount = 0; + + NET_LIST_FOR_EACH (Entry, &Nic->ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + Profile->IsAvailable = FALSE; + } + + if (Result == NULL) { + gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent); + WifiMgrFreeToken(ConfigToken); + return; + } + + for (Index = 0; Index < Result->NumOfNetworkDesc; Index ++) { + + NetworkDescription = Result->NetworkDesc + Index; + if (NetworkDescription == NULL) { + continue; + } + + Network = &NetworkDescription->Network; + if (Network == NULL || Network->SSId.SSIdLen == 0) { + continue; + } + + Status = WifiMgrCheckRSN ( + Network->AKMSuite, + Network->CipherSuite, + Nic, + &SecurityType, + &AKMSuiteSupported, + &CipherSuiteSupported + ); + if (EFI_ERROR (Status)) { + + SecurityType = SECURITY_TYPE_UNKNOWN; + AKMSuiteSupported = FALSE; + CipherSuiteSupported = FALSE; + } + + AsciiSSId = (CHAR8*) AllocateZeroPool(sizeof (CHAR8) * (Network->SSId.SSIdLen + 1)); + if (AsciiSSId == NULL) { + continue; + } + CopyMem(AsciiSSId, (CHAR8 *) Network->SSId.SSId, sizeof (CHAR8) * Network->SSId.SSIdLen); + *(AsciiSSId + Network->SSId.SSIdLen) = '\0'; + + Profile = WifiMgrGetProfileByAsciiSSId (AsciiSSId, SecurityType, &Nic->ProfileList); + if (Profile == NULL) { + + if (Nic->MaxProfileIndex >= NETWORK_LIST_COUNT_MAX) { + FreePool (AsciiSSId); + continue; + } + + // + // Create a new profile + // + Profile = AllocateZeroPool (sizeof (WIFI_MGR_NETWORK_PROFILE)); + if (Profile == NULL) { + FreePool (AsciiSSId); + continue; + } + Profile->Signature = WIFI_MGR_PROFILE_SIGNATURE; + Profile->NicIndex = Nic->NicIndex; + Profile->ProfileIndex = Nic->MaxProfileIndex + 1; + AsciiStrToUnicodeStrS (AsciiSSId, Profile->SSId, SSID_STORAGE_SIZE); + InsertTailList (&Nic->ProfileList, &Profile->Link); + Nic->MaxProfileIndex ++; + } + FreePool (AsciiSSId); + + // + //May receive duplicate networks in scan results, check if it has already + //been processed. + // + if (!Profile->IsAvailable) { + + Profile->IsAvailable = TRUE; + Profile->SecurityType = SecurityType; + Profile->AKMSuiteSupported = AKMSuiteSupported; + Profile->CipherSuiteSupported = CipherSuiteSupported; + Profile->NetworkQuality = NetworkDescription->NetworkQuality; + Nic->AvailableCount ++; + + // + //Copy BSSType and SSId + // + CopyMem(&Profile->Network, Network, sizeof (EFI_80211_NETWORK)); + + // + //Copy AKMSuite list + // + if (Network->AKMSuite != NULL) { + + if (Network->AKMSuite->AKMSuiteCount == 0) { + DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR); + } else { + DataSize = sizeof (EFI_80211_AKM_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR) + * (Network->AKMSuite->AKMSuiteCount - 1); + } + Profile->Network.AKMSuite = (EFI_80211_AKM_SUITE_SELECTOR *) AllocateZeroPool (DataSize); + if (Profile->Network.AKMSuite == NULL) { + continue; + } + CopyMem (Profile->Network.AKMSuite, Network->AKMSuite, DataSize); + } + + // + //Copy CipherSuite list + // + if (Network->CipherSuite != NULL) { + + if (Network->CipherSuite->CipherSuiteCount == 0) { + DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR); + } else { + DataSize = sizeof (EFI_80211_CIPHER_SUITE_SELECTOR) + sizeof (EFI_80211_SUITE_SELECTOR) + * (Network->CipherSuite->CipherSuiteCount - 1); + } + Profile->Network.CipherSuite = (EFI_80211_CIPHER_SUITE_SELECTOR *) AllocateZeroPool (DataSize); + if (Profile->Network.CipherSuite == NULL) { + continue; + } + CopyMem (Profile->Network.CipherSuite, Network->CipherSuite, DataSize); + } + } else { + // + // A duplicate network, update signal quality + // + if (Profile->NetworkQuality < NetworkDescription->NetworkQuality) { + Profile->NetworkQuality = NetworkDescription->NetworkQuality; + } + continue; + } + } + + gBS->SignalEvent (Nic->Private->NetworkListRefreshEvent); + + // + // The current connected network should always be available until disconnection + // happens in Wifi FW layer, even when it is not in this time's scan result. + // + if (Nic->ConnectState == WifiMgrConnectedToAp && Nic->CurrentOperateNetwork != NULL) { + if (!Nic->CurrentOperateNetwork->IsAvailable) { + Nic->CurrentOperateNetwork->IsAvailable = TRUE; + Nic->AvailableCount ++; + } + } + + WifiMgrFreeToken(ConfigToken); +} + +/** + Start scan operation, and send out a token to collect available networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED A former scan operation is already ongoing. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when getting networks from low layer. + +**/ +EFI_STATUS +WifiMgrStartScan ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_GET_NETWORKS_TOKEN *GetNetworksToken; + UINT32 HiddenSSIdIndex; + UINT32 HiddenSSIdCount; + EFI_80211_SSID *HiddenSSIdList; + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + LIST_ENTRY *Entry; + + if (Nic == NULL || Nic->Wmp == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Nic->ScanState == WifiMgrScanning) { + return EFI_ALREADY_STARTED; + } + + Nic->ScanState = WifiMgrScanning; + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = EFI_SUCCESS; + HiddenSSIdList = NULL; + HiddenSSIdCount = Nic->Private->HiddenNetworkCount; + HiddenSSIdIndex = 0; + + // + //create a new get network token + // + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + ConfigToken->Type = TokenTypeGetNetworksToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.GetNetworksToken = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_TOKEN)); + if (ConfigToken->Token.GetNetworksToken == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + GetNetworksToken = ConfigToken->Token.GetNetworksToken; + + // + // There are some hidden networks to scan, add them into scan list + // + if (HiddenSSIdCount > 0) { + HiddenSSIdList = AllocateZeroPool(HiddenSSIdCount * sizeof (EFI_80211_SSID)); + if (HiddenSSIdList == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + HiddenSSIdIndex = 0; + NET_LIST_FOR_EACH (Entry, &Nic->Private->HiddenNetworkList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, + Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + HiddenSSIdList[HiddenSSIdIndex].SSIdLen = (UINT8) StrLen (HiddenNetwork->SSId); + UnicodeStrToAsciiStrS(HiddenNetwork->SSId, + (CHAR8 *) HiddenSSIdList[HiddenSSIdIndex].SSId, SSID_STORAGE_SIZE); + HiddenSSIdIndex ++; + } + GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA) + + (HiddenSSIdCount - 1) * sizeof (EFI_80211_SSID)); + if (GetNetworksToken->Data == NULL) { + FreePool (HiddenSSIdList); + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + GetNetworksToken->Data->NumOfSSID = HiddenSSIdCount; + CopyMem(GetNetworksToken->Data->SSIDList, HiddenSSIdList, HiddenSSIdCount * sizeof (EFI_80211_SSID)); + FreePool(HiddenSSIdList); + } else { + + GetNetworksToken->Data = AllocateZeroPool (sizeof (EFI_80211_GET_NETWORKS_DATA)); + if (GetNetworksToken->Data == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + GetNetworksToken->Data->NumOfSSID = 0; + } + + // + //Create a handle when scan process ends + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnScanFinished, + ConfigToken, + &GetNetworksToken->Event + ); + if (EFI_ERROR (Status)) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + // + //Start scan ... + // + Status = Nic->Wmp->GetNetworks (Nic->Wmp, GetNetworksToken); + if (EFI_ERROR (Status)) { + Nic->ScanState = WifiMgrScanFinished; + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + gBS->RestoreTPL (OldTpl); + return EFI_SUCCESS; +} + +/** + Configure password to supplicant before connecting to a secured network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_NOT_FOUND No valid password is found to configure. + @retval Other Errors Returned errors when setting data to supplicant. + +**/ +EFI_STATUS +WifiMgrConfigPassword ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_80211_SSID SSId; + UINT8 *AsciiPassword; + + if (Nic == NULL || Nic->Supplicant == NULL || Profile == NULL) { + return EFI_INVALID_PARAMETER; + } + Supplicant = Nic->Supplicant; + // + //Set SSId to supplicant + // + SSId.SSIdLen = Profile->Network.SSId.SSIdLen; + CopyMem(SSId.SSId, Profile->Network.SSId.SSId, sizeof (Profile->Network.SSId.SSId)); + Status = Supplicant->SetData(Supplicant,EfiSupplicant80211TargetSSIDName, + (VOID *)&SSId, sizeof(EFI_80211_SSID)); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set password to supplicant + // + if (StrLen (Profile->Password) < PASSWORD_MIN_LEN) { + return EFI_NOT_FOUND; + } + AsciiPassword = AllocateZeroPool ((StrLen(Profile->Password) + 1) * sizeof (UINT8)); + if (AsciiPassword == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS (Profile->Password, (CHAR8 *) AsciiPassword, PASSWORD_STORAGE_SIZE); + Status = Supplicant->SetData (Supplicant, EfiSupplicant80211PskPassword, + AsciiPassword, (StrLen(Profile->Password) + 1) * sizeof (UINT8)); + ZeroMem (AsciiPassword, AsciiStrLen ((CHAR8 *) AsciiPassword) + 1); + FreePool(AsciiPassword); + + return Status; +} + +/** + Conduct EAP configuration to supplicant before connecting to a EAP network. + Current WiFi Connection Manager only supports three kinds of EAP networks: + 1). EAP-TLS (Two-Way Authentication is required in our implementation) + 2). EAP-TTLS/MSCHAPv2 (One-Way Authentication is required in our implementation) + 3). PEAPv0/MSCHAPv2 (One-Way Authentication is required in our implementation) + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED The expected EAP method is not supported. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Returned errors when setting data to supplicant. + +**/ +EFI_STATUS +WifiMgrConfigEap ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + EFI_EAP_CONFIGURATION_PROTOCOL *EapConfig; + EFI_EAP_TYPE EapAuthMethod; + EFI_EAP_TYPE EapSecondAuthMethod; + EFI_EAP_TYPE *AuthMethodList; + CHAR8 *Identity; + UINTN IdentitySize; + CHAR16 *Password; + UINTN PasswordSize; + UINTN EncryptPasswordLen; + CHAR8 *AsciiEncryptPassword; + UINTN AuthMethodListSize; + UINTN Index; + + if (Nic == NULL || Nic->EapConfig == NULL || Profile == NULL) { + return EFI_INVALID_PARAMETER; + } + EapConfig = Nic->EapConfig; + + if (Profile->EapAuthMethod >= EAP_AUTH_METHOD_MAX) { + return EFI_INVALID_PARAMETER; + } + EapAuthMethod = mEapAuthMethod[Profile->EapAuthMethod]; + + if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) { + if (Profile->EapSecondAuthMethod >= EAP_SEAUTH_METHOD_MAX) { + return EFI_INVALID_PARAMETER; + } + EapSecondAuthMethod = mEapSecondAuthMethod[Profile->EapSecondAuthMethod]; + } + + // + //The first time to get Supported Auth Method list, return the size. + // + AuthMethodListSize = 0; + AuthMethodList = NULL; + Status = EapConfig->GetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapSupportedAuthMethod, + (VOID *) AuthMethodList, &AuthMethodListSize); + if (Status == EFI_SUCCESS) { + // + //No Supported Eap Auth Method + // + return EFI_UNSUPPORTED; + } else if (Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + + // + // The second time to get Supported Auth Method list, return the list. + // In current design, only EAPTLS, TTLS and PEAP are supported + // + AuthMethodList = (EFI_EAP_TYPE *) AllocateZeroPool(AuthMethodListSize); + if (AuthMethodList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = EapConfig->GetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapSupportedAuthMethod, + (VOID *) AuthMethodList, &AuthMethodListSize); + if (EFI_ERROR (Status)) { + FreePool (AuthMethodList); + return Status; + } + + // + //Check if EapAuthMethod is in supported Auth Method list, if found, skip the loop. + // + for (Index = 0; Index < AuthMethodListSize / sizeof (EFI_EAP_TYPE); Index ++) { + if (EapAuthMethod == AuthMethodList[Index]) { + break; + } + } + if (Index == AuthMethodListSize / sizeof (EFI_EAP_TYPE)) { + FreePool (AuthMethodList); + return EFI_UNSUPPORTED; + } + FreePool (AuthMethodList); + + // + // Set Identity to Eap peer, Mandatory field for PEAP and TTLS + // + if (StrLen (Profile->EapIdentity) > 0) { + + IdentitySize = sizeof(CHAR8) * (StrLen(Profile->EapIdentity) + 1); + Identity = AllocateZeroPool (IdentitySize); + if (Identity == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS(Profile->EapIdentity, Identity, IdentitySize); + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_IDENTITY, EfiEapConfigIdentityString, + (VOID *) Identity, IdentitySize - 1); + if (EFI_ERROR(Status)) { + FreePool (Identity); + return Status; + } + FreePool (Identity); + } else { + if (EapAuthMethod != EFI_EAP_TYPE_EAPTLS) { + return EFI_INVALID_PARAMETER; + } + } + + // + //Set Auth Method to Eap peer, Mandatory field + // + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_ATTRIBUTE, EfiEapConfigEapAuthMethod, + (VOID *) &EapAuthMethod, sizeof (EapAuthMethod)); + if (EFI_ERROR(Status)) { + return Status; + } + + if (EapAuthMethod == EFI_EAP_TYPE_TTLS || EapAuthMethod == EFI_EAP_TYPE_PEAP) { + + Status = EapConfig->SetData (EapConfig, EapAuthMethod, EfiEapConfigEap2ndAuthMethod, + (VOID *) &EapSecondAuthMethod, sizeof (EapSecondAuthMethod)); + if (EFI_ERROR(Status)) { + return Status; + } + + // + // Set Password to Eap peer + // + if (StrLen (Profile->EapPassword) < PASSWORD_MIN_LEN) { + + DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Eap Password for Network: %s.\n", Profile->SSId)); + return EFI_INVALID_PARAMETER; + } + + PasswordSize = sizeof (CHAR16) * (StrLen (Profile->EapPassword) + 1); + Password = AllocateZeroPool (PasswordSize); + if (Password == NULL) { + return EFI_OUT_OF_RESOURCES; + } + StrCpyS (Password, PasswordSize, Profile->EapPassword);; + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_MSCHAPV2, EfiEapConfigEapMSChapV2Password, + (VOID *) Password, PasswordSize); + ZeroMem (Password, PasswordSize); + FreePool (Password); + if (EFI_ERROR (Status)) { + return Status; + } + + // + //If CA cert is required, set it to Eap peer + // + if (Profile->CACertData != NULL) { + + Status = EapConfig->SetData (EapConfig, EapAuthMethod, EfiEapConfigEapTlsCACert, + Profile->CACertData, Profile->CACertSize); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + return EFI_INVALID_PARAMETER; + } + } else if (EapAuthMethod == EFI_EAP_TYPE_EAPTLS) { + + // + //Set CA cert to Eap peer + // + if (Profile->CACertData == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsCACert, + Profile->CACertData, Profile->CACertSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set Client cert to Eap peer + // + if (Profile->ClientCertData == NULL) { + return EFI_INVALID_PARAMETER; + } + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsClientCert, + Profile->ClientCertData, Profile->ClientCertSize); + if (EFI_ERROR(Status)) { + return Status; + } + + // + //Set Private key to Eap peer + // + if (Profile->PrivateKeyData == NULL) { + + DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: No Private Key for Network: %s.\n", Profile->SSId)); + return EFI_INVALID_PARAMETER; + } + + Status = EapConfig->SetData (EapConfig, EFI_EAP_TYPE_EAPTLS, EfiEapConfigEapTlsClientPrivateKeyFile, + Profile->PrivateKeyData, Profile->PrivateKeyDataSize); + if (EFI_ERROR(Status)) { + return Status; + } + + if (StrLen (Profile->PrivateKeyPassword) > 0) { + + EncryptPasswordLen = StrLen (Profile->PrivateKeyPassword); + AsciiEncryptPassword = AllocateZeroPool(EncryptPasswordLen + 1); + if (AsciiEncryptPassword == NULL) { + return EFI_OUT_OF_RESOURCES; + } + UnicodeStrToAsciiStrS(Profile->PrivateKeyPassword, AsciiEncryptPassword, EncryptPasswordLen + 1); + Status = EapConfig->SetData(EapConfig, EFI_EAP_TYPE_EAPTLS, + EfiEapConfigEapTlsClientPrivateKeyFilePassword, + (VOID *) AsciiEncryptPassword, EncryptPasswordLen + 1); + if (EFI_ERROR(Status)) { + + ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1); + FreePool (AsciiEncryptPassword); + return Status; + } + + ZeroMem (AsciiEncryptPassword, EncryptPasswordLen + 1); + FreePool (AsciiEncryptPassword); + } + } else { + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Get current link state from low layer. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[out] LinkState The pointer to buffer to retrieve link state. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED Adapter information protocol is not supported. + @retval Other Errors Returned errors when retrieving link state from low layer. + +**/ +EFI_STATUS +WifiMgrGetLinkState ( + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + UINTN DataSize; + EFI_ADAPTER_INFO_MEDIA_STATE *UndiState; + EFI_ADAPTER_INFORMATION_PROTOCOL *Aip; + + if (Nic == NULL || LinkState == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = gBS->OpenProtocol ( + Nic->ControllerHandle, + &gEfiAdapterInformationProtocolGuid, + (VOID**) &Aip, + Nic->DriverHandle, + Nic->ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + return EFI_UNSUPPORTED; + } + + Status = Aip->GetInformation( + Aip, + &gEfiAdapterInfoMediaStateGuid, + (VOID **) &UndiState, + &DataSize + ); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + return Status; + } + gBS->RestoreTPL (OldTpl); + + CopyMem (LinkState, UndiState, sizeof (EFI_ADAPTER_INFO_MEDIA_STATE)); + FreePool (UndiState); + return EFI_SUCCESS; +} + +/** + Prepare configuration work before connecting to the target network. + For WPA2 Personal networks, password should be checked; and for EAP networks, parameters + are different for different networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_UNSUPPORTED This network is not supported. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + +**/ +EFI_STATUS +WifiMgrPrepareConnection ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + UINT8 SecurityType; + BOOLEAN AKMSuiteSupported; + BOOLEAN CipherSuiteSupported; + + if (Profile == NULL || Nic == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = WifiMgrCheckRSN (Profile->Network.AKMSuite, Profile->Network.CipherSuite, + Nic, &SecurityType, &AKMSuiteSupported, &CipherSuiteSupported); + if (EFI_ERROR (Status)) { + return Status; + } + + if (AKMSuiteSupported && CipherSuiteSupported) { + switch (SecurityType) { + case SECURITY_TYPE_WPA2_PERSONAL: + + Status = WifiMgrConfigPassword (Nic, Profile); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + if (Nic->OneTimeConnectRequest) { + WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Password!"); + } + } + return Status; + } + break; + + case SECURITY_TYPE_WPA2_ENTERPRISE: + + Status = WifiMgrConfigEap (Nic, Profile); + if (EFI_ERROR (Status)) { + if (Status == EFI_INVALID_PARAMETER) { + if (Nic->OneTimeConnectRequest) { + WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Invalid Configuration!"); + } + } + return Status; + } + break; + + case SECURITY_TYPE_NONE: + break; + + default: + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + The callback function for connect operation. + + ASSERT when errors occur in config token. + + @param[in] Event The Connect token receive event. + @param[in] Context The context of the connect token. + +**/ +VOID +EFIAPI +WifiMgrOnConnectFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + WIFI_MGR_NETWORK_PROFILE *ConnectedProfile; + UINT8 SecurityType; + UINT8 SSIdLen; + CHAR8 *AsciiSSId; + + ASSERT (Context != NULL); + + ConnectedProfile = NULL; + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN*) Context; + ASSERT (ConfigToken->Nic != NULL); + + ConfigToken->Nic->ConnectState = WifiMgrDisconnected; + ASSERT (ConfigToken->Type == TokenTypeConnectNetworkToken); + + ASSERT (ConfigToken->Token.ConnectNetworkToken != NULL); + if (ConfigToken->Token.ConnectNetworkToken->Status != EFI_SUCCESS) { + + if (ConfigToken->Nic->OneTimeConnectRequest) { + // + // Only update message for user triggered connection + // + if (ConfigToken->Token.ConnectNetworkToken->Status == EFI_ACCESS_DENIED) { + + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Permission Denied!"); + } else { + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!"); + } + ConfigToken->Nic->OneTimeConnectRequest = FALSE; + } + ConfigToken->Nic->CurrentOperateNetwork = NULL; + return; + } + + if (ConfigToken->Token.ConnectNetworkToken->ResultCode != ConnectSuccess) { + + if (ConfigToken->Nic->OneTimeConnectRequest) { + + if (ConfigToken->Token.ConnectNetworkToken->ResultCode == ConnectFailedReasonUnspecified) { + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed: Wrong Password or Unexpected Error!"); + } else { + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Connect Failed!"); + } + } + goto Exit; + } + + if (ConfigToken->Token.ConnectNetworkToken->Data == NULL || + ConfigToken->Token.ConnectNetworkToken->Data->Network == NULL) { + + // + // An unexpected error occurs, tell low layer to perform a disconnect + // + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + goto Exit; + } + + // + // A correct connect token received, terminate the connection process + // + Status = WifiMgrCheckRSN(ConfigToken->Token.ConnectNetworkToken->Data->Network->AKMSuite, + ConfigToken->Token.ConnectNetworkToken->Data->Network->CipherSuite, + ConfigToken->Nic, &SecurityType, NULL, NULL); + if (EFI_ERROR(Status)) { + SecurityType = SECURITY_TYPE_UNKNOWN; + } + + SSIdLen = ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSIdLen; + AsciiSSId = (CHAR8*) AllocateZeroPool(sizeof (CHAR8) * (SSIdLen + 1)); + if (AsciiSSId == NULL) { + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + goto Exit; + } + + CopyMem(AsciiSSId, ConfigToken->Token.ConnectNetworkToken->Data->Network->SSId.SSId, SSIdLen); + *(AsciiSSId + SSIdLen) = '\0'; + + ConnectedProfile = WifiMgrGetProfileByAsciiSSId(AsciiSSId, SecurityType, &ConfigToken->Nic->ProfileList); + FreePool(AsciiSSId); + if (ConnectedProfile == NULL) { + ConfigToken->Nic->HasDisconnectPendingNetwork = TRUE; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + goto Exit; + } + + ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL); + +Exit: + + if (ConfigToken->Nic->ConnectState == WifiMgrDisconnected) { + ConfigToken->Nic->CurrentOperateNetwork = NULL; + } + ConfigToken->Nic->OneTimeConnectRequest = FALSE; + WifiMgrFreeToken(ConfigToken); +} + +/** + Start connect operation, and send out a token to connect to a target network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect + operation first. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when connecting network on low layer. + +**/ +EFI_STATUS +WifiMgrConnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + EFI_ADAPTER_INFO_MEDIA_STATE LinkState; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_CONNECT_NETWORK_TOKEN *ConnectToken; + + if (Nic == NULL || Nic->Wmp == NULL || Profile == NULL) { + return EFI_INVALID_PARAMETER; + } + + Status = WifiMgrGetLinkState (Nic, &LinkState); + if (EFI_ERROR (Status)) { + return Status; + } + if (LinkState.MediaState == EFI_SUCCESS) { + return EFI_ALREADY_STARTED; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = WifiMgrPrepareConnection (Nic, Profile); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + return Status; + } + + // + // Create a new connect token + // + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + ConfigToken->Type = TokenTypeConnectNetworkToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.ConnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_TOKEN)); + if (ConfigToken->Token.ConnectNetworkToken == NULL) { + goto Exit; + } + + ConnectToken = ConfigToken->Token.ConnectNetworkToken; + ConnectToken->Data = AllocateZeroPool (sizeof (EFI_80211_CONNECT_NETWORK_DATA)); + if (ConnectToken->Data == NULL) { + goto Exit; + } + + ConnectToken->Data->Network = AllocateZeroPool (sizeof (EFI_80211_NETWORK)); + if (ConnectToken->Data->Network == NULL) { + goto Exit; + } + CopyMem(ConnectToken->Data->Network, &Profile->Network, sizeof (EFI_80211_NETWORK)); + + // + // Add event handle and start to connect + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnConnectFinished, + ConfigToken, + &ConnectToken->Event + ); + if (EFI_ERROR (Status)) { + goto Exit; + } + + Nic->ConnectState = WifiMgrConnectingToAp; + Nic->CurrentOperateNetwork = Profile; + WifiMgrUpdateConnectMessage (Nic, FALSE, NULL); + + // + //Start Connecting ... + // + Status = Nic->Wmp->ConnectNetwork (Nic->Wmp, ConnectToken); + + // + // Erase secrets after connection is triggered + // + WifiMgrCleanProfileSecrets (Profile); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ALREADY_STARTED) { + Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (Nic, TRUE, NULL); + } else { + + Nic->ConnectState = WifiMgrDisconnected; + Nic->CurrentOperateNetwork = NULL; + + if (Nic->OneTimeConnectRequest) { + if (Status == EFI_NOT_FOUND) { + WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Not Available!"); + } else { + WifiMgrUpdateConnectMessage (Nic, FALSE, L"Connect Failed: Unexpected Error!"); + } + } + } + goto Exit; + } + +Exit: + + if (EFI_ERROR (Status)) { + WifiMgrFreeToken (ConfigToken); + } + gBS->RestoreTPL (OldTpl); + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] WifiMgrConnectToNetwork: %r\n", Status)); + return Status; +} + +/** + The callback function for disconnect operation. + + ASSERT when errors occur in config token. + + @param[in] Event The Disconnect token receive event. + @param[in] Context The context of the Disconnect token. + +**/ +VOID +EFIAPI +WifiMgrOnDisconnectFinished ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + + ASSERT (Context != NULL); + + ConfigToken = (WIFI_MGR_MAC_CONFIG_TOKEN*) Context; + ASSERT (ConfigToken->Nic != NULL); + ASSERT (ConfigToken->Type == TokenTypeDisconnectNetworkToken); + + ASSERT (ConfigToken->Token.DisconnectNetworkToken != NULL); + if (ConfigToken->Token.DisconnectNetworkToken->Status != EFI_SUCCESS) { + ConfigToken->Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + ConfigToken->Nic->OneTimeDisconnectRequest = FALSE; + goto Exit; + } + + ConfigToken->Nic->ConnectState = WifiMgrDisconnected; + ConfigToken->Nic->CurrentOperateNetwork = NULL; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL); + ConfigToken->Nic->OneTimeDisconnectRequest = FALSE; + + // + // Disconnected network may not be in network list now, trigger a scan again! + // + ConfigToken->Nic->OneTimeScanRequest = TRUE; + + Exit: + WifiMgrFreeToken(ConfigToken); + return; +} + +/** + Start disconnect operation, and send out a token to disconnect from current connected + network. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval Other Errors Return errors when disconnecting a network on low layer. + +**/ +EFI_STATUS +WifiMgrDisconnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken; + EFI_80211_DISCONNECT_NETWORK_TOKEN *DisconnectToken; + + if (Nic == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + Status = EFI_SUCCESS; + ConfigToken = AllocateZeroPool (sizeof (WIFI_MGR_MAC_CONFIG_TOKEN)); + if (ConfigToken == NULL) { + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + ConfigToken->Type = TokenTypeDisconnectNetworkToken; + ConfigToken->Nic = Nic; + ConfigToken->Token.DisconnectNetworkToken = AllocateZeroPool (sizeof (EFI_80211_DISCONNECT_NETWORK_TOKEN)); + if (ConfigToken->Token.DisconnectNetworkToken == NULL) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return EFI_OUT_OF_RESOURCES; + } + + DisconnectToken = ConfigToken->Token.DisconnectNetworkToken; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + WifiMgrOnDisconnectFinished, + ConfigToken, + &DisconnectToken->Event + ); + if (EFI_ERROR (Status)) { + WifiMgrFreeToken(ConfigToken); + gBS->RestoreTPL (OldTpl); + return Status; + } + + Nic->ConnectState = WifiMgrDisconnectingToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + + Status = Nic->Wmp->DisconnectNetwork (Nic->Wmp, DisconnectToken); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + + Nic->ConnectState = WifiMgrDisconnected; + Nic->CurrentOperateNetwork = NULL; + + // + // This network is not in network list now, trigger a scan again! + // + Nic->OneTimeScanRequest = TRUE; + + // + // State has been changed from Connected to Disconnected + // + WifiMgrUpdateConnectMessage (ConfigToken->Nic, TRUE, NULL); + Status = EFI_SUCCESS; + } else { + if (Nic->OneTimeDisconnectRequest) { + + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, L"Disconnect Failed: Unexpected Error!"); + } + + Nic->ConnectState = WifiMgrConnectedToAp; + WifiMgrUpdateConnectMessage (ConfigToken->Nic, FALSE, NULL); + } + WifiMgrFreeToken(ConfigToken); + } + + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + The state machine of the connection manager, periodically check the state and + perform a corresponding operation. + + @param[in] Event The timer event to be triggered. + @param[in] Context The context of the Nic device data. + +**/ +VOID +EFIAPI +WifiMgrOnTimerTick ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + WIFI_MGR_DEVICE_DATA *Nic; + EFI_STATUS Status; + EFI_ADAPTER_INFO_MEDIA_STATE LinkState; + WIFI_MGR_NETWORK_PROFILE *Profile; + + if (Context == NULL) { + return; + } + + Nic = (WIFI_MGR_DEVICE_DATA*) Context; + NET_CHECK_SIGNATURE (Nic, WIFI_MGR_DEVICE_DATA_SIGNATURE); + + Status = WifiMgrGetLinkState (Nic, &LinkState); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Error: Failed to get link state!\n")); + return; + } + + if (Nic->LastLinkState.MediaState != LinkState.MediaState) { + if (Nic->LastLinkState.MediaState == EFI_SUCCESS && LinkState.MediaState == EFI_NO_MEDIA) { + Nic->HasDisconnectPendingNetwork = TRUE; + } + Nic->LastLinkState.MediaState = LinkState.MediaState; + } + + Nic->ScanTickTime ++; + if ((Nic->ScanTickTime > WIFI_SCAN_FREQUENCY || Nic->OneTimeScanRequest) && + Nic->ScanState == WifiMgrScanFinished) { + + Nic->OneTimeScanRequest = FALSE; + Nic->ScanTickTime = 0; + + DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Scan is triggered.\n")); + WifiMgrStartScan (Nic); + } + + if (Nic->AvailableCount > 0 && Nic->ScanState == WifiMgrScanFinished) { + + switch (Nic->ConnectState) { + case WifiMgrDisconnected: + + if (Nic->HasDisconnectPendingNetwork) { + Nic->HasDisconnectPendingNetwork = FALSE; + } + + if (Nic->ConnectPendingNetwork != NULL) { + + Profile = Nic->ConnectPendingNetwork; + Status = WifiMgrConnectToNetwork(Nic, Profile); + Nic->ConnectPendingNetwork = NULL; + if (EFI_ERROR (Status)) { + // + // Some error happened, don't wait for a return connect token! + // + Nic->OneTimeConnectRequest = FALSE; + } + } + break; + + case WifiMgrConnectingToAp: + break; + + case WifiMgrDisconnectingToAp: + break; + + case WifiMgrConnectedToAp: + + if (Nic->ConnectPendingNetwork != NULL || Nic->HasDisconnectPendingNetwork) { + + Status = WifiMgrDisconnectToNetwork(Nic); + if (EFI_ERROR (Status)) { + // + // Some error happened, don't wait for a return disconnect token! + // + Nic->OneTimeDisconnectRequest = FALSE; + } + } + break; + + default: + break; + } + } +} diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h new file mode 100644 index 00000000..bcac7f80 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrImpl.h @@ -0,0 +1,99 @@ +/** @file + The Mac Connection2 Protocol adapter functions for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_IMPL__ +#define __EFI_WIFI_IMPL__ + +/** + Start scan operation, and send out a token to collect available networks. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED A former scan operation is already ongoing. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when getting networks from low layer. + +**/ +EFI_STATUS +WifiMgrStartScan ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + Get current link state from low layer. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[out] LinkState The pointer to buffer to retrieve link state. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_UNSUPPORTED Adapter information protocol is not supported. + @retval Other Errors Returned errors when retrieving link state from low layer. + +**/ +EFI_STATUS +WifiMgrGetLinkState ( + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT EFI_ADAPTER_INFO_MEDIA_STATE *LinkState + ); + +/** + Start connect operation, and send out a token to connect to a target network. + + @param[in] Nic Pointer to the device data of the selected NIC. + @param[in] Profile The target network to be connected. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_ALREADY_STARTED Already in "connected" state, need to perform a disconnect + operation first. + @retval EFI_INVALID_PARAMETER One or more parameters are invalid. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when connecting network on low layer. + +**/ +EFI_STATUS +WifiMgrConnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic, + IN WIFI_MGR_NETWORK_PROFILE *Profile + ); + +/** + Start disconnect operation, and send out a token to disconnect from current connected + network. + + @param[in] Nic Pointer to the device data of the selected NIC. + + @retval EFI_SUCCESS The operation is completed. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + @retval Other Errors Return errors when disconnecting a network on low layer. + +**/ +EFI_STATUS +WifiMgrDisconnectToNetwork ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + The state machine of the connection manager, periodically check the state and + perform a corresponding operation. + + @param[in] Event The timer event to be triggered. + @param[in] Context The context of the Nic device data. + +**/ +VOID +EFIAPI +WifiMgrOnTimerTick ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +#endif diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c new file mode 100644 index 00000000..4233718b --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.c @@ -0,0 +1,744 @@ +/** @file + The Miscellaneous Routines for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "WifiConnectionMgrDxe.h" + +/** + Empty function for event process function. + + @param Event The Event need to be process + @param Context The context of the event. + +**/ +VOID +EFIAPI +WifiMgrInternalEmptyFunction ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + return; +} + +/** + Convert the mac address into a hexadecimal encoded ":" seperated string. + + @param[in] Mac The mac address. + @param[in] StrSize The size, in bytes, of the output buffer specified by Str. + @param[out] Str The storage to return the mac string. + +**/ +VOID +WifiMgrMacAddrToStr ( + IN EFI_80211_MAC_ADDRESS *Mac, + IN UINT32 StrSize, + OUT CHAR16 *Str + ) +{ + if (Mac == NULL || Str == NULL) { + return; + } + + UnicodeSPrint ( + Str, + StrSize, + L"%02X:%02X:%02X:%02X:%02X:%02X", + Mac->Addr[0], Mac->Addr[1], Mac->Addr[2], + Mac->Addr[3], Mac->Addr[4], Mac->Addr[5] + ); +} + +/** + Read private key file to buffer. + + @param[in] FileContext The file context of private key file. + @param[out] PrivateKeyDataAddr The buffer address to restore private key file, should be + freed by caller. + @param[out] PrivateKeyDataSize The size of read private key file. + + @retval EFI_SUCCESS Successfully read the private key file. + @retval EFI_INVALID_PARAMETER One or more of the parameters is invalid. + +**/ +EFI_STATUS +WifiMgrReadFileToBuffer ( + IN WIFI_MGR_FILE_CONTEXT *FileContext, + OUT VOID **DataAddr, + OUT UINTN *DataSize + ) +{ + EFI_STATUS Status; + + if (FileContext != NULL && FileContext->FHandle != NULL) { + + Status = ReadFileContent ( + FileContext->FHandle, + DataAddr, + DataSize, + 0 + ); + + if (FileContext->FHandle != NULL) { + FileContext->FHandle->Close (FileContext->FHandle); + } + FileContext->FHandle = NULL; + return Status; + } + + return EFI_INVALID_PARAMETER; +} + +/** + Get the Nic data by the NicIndex. + + @param[in] Private The pointer to the global private data structure. + @param[in] NicIndex The index indicates the position of wireless NIC. + + @return Pointer to the Nic data, or NULL if not found. + +**/ +WIFI_MGR_DEVICE_DATA * +WifiMgrGetNicByIndex ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN UINT32 NicIndex + ) +{ + LIST_ENTRY *Entry; + WIFI_MGR_DEVICE_DATA *Nic; + + if (Private == NULL) { + return NULL; + } + + NET_LIST_FOR_EACH (Entry, &Private->NicList) { + Nic = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_DEVICE_DATA, + Link, WIFI_MGR_DEVICE_DATA_SIGNATURE); + if (Nic->NicIndex == NicIndex) { + return Nic; + } + } + + return NULL; +} + +/** + Find a network profile through its' SSId and securit type, and the SSId is an unicode string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByUnicodeSSId ( + IN CHAR16 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ) +{ + LIST_ENTRY *Entry; + WIFI_MGR_NETWORK_PROFILE *Profile; + + if (SSId == NULL || ProfileList == NULL) { + return NULL; + } + + NET_LIST_FOR_EACH (Entry, ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + if (StrCmp (SSId, Profile->SSId) == 0 && SecurityType == Profile->SecurityType) { + return Profile; + } + } + + return NULL; +} + +/** + Find a network profile through its' SSId and securit type, and the SSId is an ascii string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByAsciiSSId ( + IN CHAR8 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ) +{ + CHAR16 SSIdUniCode[SSID_STORAGE_SIZE]; + + if (SSId == NULL) { + return NULL; + } + if (AsciiStrToUnicodeStrS (SSId, SSIdUniCode, SSID_STORAGE_SIZE) != RETURN_SUCCESS) { + return NULL; + } + + return WifiMgrGetProfileByUnicodeSSId (SSIdUniCode, SecurityType, ProfileList); +} + +/** + Find a network profile through its' profile index. + + @param[in] ProfileIndex The target network's profile index. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByProfileIndex ( + IN UINT32 ProfileIndex, + IN LIST_ENTRY *ProfileList + ) +{ + WIFI_MGR_NETWORK_PROFILE *Profile; + LIST_ENTRY *Entry; + + if (ProfileList == NULL) { + return NULL; + } + NET_LIST_FOR_EACH (Entry, ProfileList) { + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + if (Profile->ProfileIndex == ProfileIndex) { + return Profile; + } + } + return NULL; +} + +/** + To test if the AKMSuite is in supported AKMSuite list. + + @param[in] SupportedAKMSuiteCount The count of the supported AKMSuites. + @param[in] SupportedAKMSuiteList The supported AKMSuite list. + @param[in] AKMSuite The AKMSuite to be tested. + + @return True if this AKMSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportAKMSuite ( + IN UINT16 SupportedAKMSuiteCount, + IN UINT32 *SupportedAKMSuiteList, + IN UINT32 *AKMSuite + ) +{ + UINT16 Index; + + if (AKMSuite == NULL || SupportedAKMSuiteList == NULL || + SupportedAKMSuiteCount == 0) { + return FALSE; + } + + for (Index = 0; Index < SupportedAKMSuiteCount; Index ++) { + if (SupportedAKMSuiteList[Index] == *AKMSuite) { + return TRUE; + } + } + + return FALSE; +} + +/** + To check if the CipherSuite is in supported CipherSuite list. + + @param[in] SupportedCipherSuiteCount The count of the supported CipherSuites. + @param[in] SupportedCipherSuiteList The supported CipherSuite list. + @param[in] CipherSuite The CipherSuite to be tested. + + @return True if this CipherSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportCipherSuite ( + IN UINT16 SupportedCipherSuiteCount, + IN UINT32 *SupportedCipherSuiteList, + IN UINT32 *CipherSuite + ) +{ + UINT16 Index; + + if (CipherSuite == NULL || SupportedCipherSuiteCount == 0 || + SupportedCipherSuiteList == NULL) { + return FALSE; + } + + for (Index = 0; Index < SupportedCipherSuiteCount; Index ++) { + if (SupportedCipherSuiteList[Index] == *CipherSuite) { + return TRUE; + } + } + + return FALSE; +} + +/** + Check an AKM suite list and a Cipher suite list to see if one or more AKM suites or Cipher suites + are supported and find the matchable security type. + + @param[in] AKMList The target AKM suite list to be checked. + @param[in] CipherList The target Cipher suite list to be checked + @param[in] Nic The Nic to operate, contains the supported AKMSuite list + and supported CipherSuite list + @param[out] SecurityType To identify a security type from the AKM suite list and + Cipher suite list + @param[out] AKMSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + @param[out] CipherSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + + @retval EFI_SUCCESS This operation has completed successfully. + @retval EFI_INVALID_PARAMETER No Nic found or the suite list is null. + +**/ +EFI_STATUS +WifiMgrCheckRSN ( + IN EFI_80211_AKM_SUITE_SELECTOR *AKMList, + IN EFI_80211_CIPHER_SUITE_SELECTOR *CipherList, + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT UINT8 *SecurityType, + OUT BOOLEAN *AKMSuiteSupported, + OUT BOOLEAN *CipherSuiteSupported + ) +{ + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; + EFI_80211_SUITE_SELECTOR *AKMSuite; + EFI_80211_SUITE_SELECTOR *CipherSuite; + UINT16 AKMIndex; + UINT16 CipherIndex; + + if (Nic == NULL || AKMList == NULL || CipherList == NULL|| SecurityType == NULL) { + return EFI_INVALID_PARAMETER; + } + + SupportedAKMSuites = Nic->SupportedSuites.SupportedAKMSuites; + SupportedSwCipherSuites = Nic->SupportedSuites.SupportedSwCipherSuites; + SupportedHwCipherSuites = Nic->SupportedSuites.SupportedHwCipherSuites; + + *SecurityType = SECURITY_TYPE_UNKNOWN; + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = FALSE; + *CipherSuiteSupported = FALSE; + } + + if (AKMList->AKMSuiteCount == 0) { + if (CipherList->CipherSuiteCount == 0) { + *SecurityType = SECURITY_TYPE_NONE; + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = TRUE; + *CipherSuiteSupported = TRUE; + } + } + + return EFI_SUCCESS; + } + + for (AKMIndex = 0; AKMIndex < AKMList->AKMSuiteCount; AKMIndex ++) { + + AKMSuite = AKMList->AKMSuiteList + AKMIndex; + if (WifiMgrSupportAKMSuite(SupportedAKMSuites->AKMSuiteCount, + (UINT32*) SupportedAKMSuites->AKMSuiteList, (UINT32*) AKMSuite)) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *AKMSuiteSupported = TRUE; + } + for (CipherIndex = 0; CipherIndex < CipherList->CipherSuiteCount; CipherIndex ++) { + + CipherSuite = CipherList->CipherSuiteList + CipherIndex; + + if (SupportedSwCipherSuites != NULL) { + + if (WifiMgrSupportCipherSuite(SupportedSwCipherSuites->CipherSuiteCount, + (UINT32*) SupportedSwCipherSuites->CipherSuiteList, (UINT32*) CipherSuite)) { + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMSuite, (UINT32*) CipherSuite); + + if (*SecurityType != SECURITY_TYPE_UNKNOWN) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *CipherSuiteSupported = TRUE; + } + return EFI_SUCCESS; + } + } + } + + if (SupportedHwCipherSuites != NULL) { + + if (WifiMgrSupportCipherSuite(SupportedHwCipherSuites->CipherSuiteCount, + (UINT32*) SupportedHwCipherSuites->CipherSuiteList, (UINT32*) CipherSuite)) { + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMSuite, (UINT32*) CipherSuite); + + if (*SecurityType != SECURITY_TYPE_UNKNOWN) { + + if (AKMSuiteSupported != NULL && CipherSuiteSupported != NULL) { + *CipherSuiteSupported = TRUE; + } + return EFI_SUCCESS; + } + } + } + } + } + } + + *SecurityType = WifiMgrGetSecurityType ((UINT32*) AKMList->AKMSuiteList, + (UINT32*) CipherList->CipherSuiteList); + + return EFI_SUCCESS; +} + +/** + Get the security type for a certain AKMSuite and CipherSuite. + + @param[in] AKMSuite An certain AKMSuite. + @param[in] CipherSuite An certain CipherSuite. + + @return a security type if found, or SECURITY_TYPE_UNKNOWN. + +**/ +UINT8 +WifiMgrGetSecurityType ( + IN UINT32 *AKMSuite, + IN UINT32 *CipherSuite + ) +{ + if (CipherSuite == NULL) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_NONE; + } else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_USE_GROUP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_NONE; + } else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP40 || + *CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_WEP104) { + + return SECURITY_TYPE_WEP; + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_CCMP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_UNKNOWN; + } + + if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA || + *AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256) { + + return SECURITY_TYPE_WPA2_ENTERPRISE; + } else if (*AKMSuite == IEEE_80211_AKM_SUITE_PSK || + *AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256){ + + return SECURITY_TYPE_WPA2_PERSONAL; + }else { + return SECURITY_TYPE_UNKNOWN; + } + } else if (*CipherSuite == IEEE_80211_PAIRWISE_CIPHER_SUITE_TKIP) { + + if (AKMSuite == NULL) { + return SECURITY_TYPE_UNKNOWN; + } + + if (*AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA || + *AKMSuite == IEEE_80211_AKM_SUITE_8021X_OR_PMKSA_SHA256) { + + return SECURITY_TYPE_WPA_ENTERPRISE; + } else if (*AKMSuite == IEEE_80211_AKM_SUITE_PSK || + *AKMSuite == IEEE_80211_AKM_SUITE_PSK_SHA256){ + + return SECURITY_TYPE_WPA_PERSONAL; + }else { + return SECURITY_TYPE_UNKNOWN; + } + } else { + return SECURITY_TYPE_UNKNOWN; + } +} + +/** + Get supported AKMSuites and CipherSuites from supplicant for a Nic. + + @param[in] Nic The Nic to operate. + + @retval EFI_SUCCESS Get the supported suite list successfully. + @retval EFI_INVALID_PARAMETER No Nic found or supplicant is NULL. + +**/ +EFI_STATUS +WifiMgrGetSupportedSuites ( + IN WIFI_MGR_DEVICE_DATA *Nic + ) +{ + EFI_STATUS Status; + EFI_SUPPLICANT_PROTOCOL *Supplicant; + EFI_80211_AKM_SUITE_SELECTOR *SupportedAKMSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedSwCipherSuites; + EFI_80211_CIPHER_SUITE_SELECTOR *SupportedHwCipherSuites; + UINTN DataSize; + + SupportedAKMSuites = NULL; + SupportedSwCipherSuites = NULL; + SupportedHwCipherSuites = NULL; + + if (Nic == NULL || Nic->Supplicant == NULL) { + return EFI_INVALID_PARAMETER; + } + + Supplicant = Nic->Supplicant; + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedAKMSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + SupportedAKMSuites = AllocateZeroPool(DataSize); + if (SupportedAKMSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedAKMSuites, + (UINT8 *) SupportedAKMSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedAKMSuites = SupportedAKMSuites; + } else { + FreePool (SupportedAKMSuites); + } + } else { + SupportedAKMSuites = NULL; + } + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedSoftwareCipherSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + + SupportedSwCipherSuites = AllocateZeroPool(DataSize); + if (SupportedSwCipherSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedSoftwareCipherSuites, + (UINT8 *) SupportedSwCipherSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedSwCipherSuites = SupportedSwCipherSuites; + } else { + FreePool (SupportedSwCipherSuites); + } + } else { + SupportedSwCipherSuites = NULL; + } + + DataSize = 0; + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedHardwareCipherSuites, NULL, &DataSize); + if (Status == EFI_BUFFER_TOO_SMALL && DataSize > 0) { + + SupportedHwCipherSuites = AllocateZeroPool(DataSize); + if (SupportedHwCipherSuites == NULL) { + return EFI_OUT_OF_RESOURCES; + } + Status = Supplicant->GetData (Supplicant, EfiSupplicant80211SupportedHardwareCipherSuites, + (UINT8 *) SupportedHwCipherSuites, &DataSize); + if (!EFI_ERROR (Status)) { + Nic->SupportedSuites.SupportedHwCipherSuites = SupportedHwCipherSuites; + } else { + FreePool (SupportedHwCipherSuites); + } + } else { + SupportedHwCipherSuites = NULL; + } + + return EFI_SUCCESS; +} + +/** + Clean secrets from a network profile. + + @param[in] Profile The profile to be cleanned. + +**/ +VOID +WifiMgrCleanProfileSecrets ( + IN WIFI_MGR_NETWORK_PROFILE *Profile + ) +{ + ZeroMem (Profile->Password, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + ZeroMem (Profile->EapPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + ZeroMem (Profile->PrivateKeyPassword, sizeof (CHAR16) * PASSWORD_STORAGE_SIZE); + + if (Profile->CACertData != NULL) { + + ZeroMem (Profile->CACertData, Profile->CACertSize); + FreePool (Profile->CACertData); + } + Profile->CACertData = NULL; + Profile->CACertSize = 0; + + if (Profile->ClientCertData != NULL) { + + ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); + FreePool (Profile->ClientCertData); + } + Profile->ClientCertData = NULL; + Profile->ClientCertSize = 0; + + if (Profile->PrivateKeyData != NULL) { + + ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize); + FreePool (Profile->PrivateKeyData); + } + Profile->PrivateKeyData = NULL; + Profile->PrivateKeyDataSize = 0; +} + +/** + Free all network profiles in a profile list. + + @param[in] ProfileList The profile list to be freed. + +**/ +VOID +WifiMgrFreeProfileList ( + IN LIST_ENTRY *ProfileList + ) +{ + WIFI_MGR_NETWORK_PROFILE *Profile; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if (ProfileList == NULL) { + return; + } + + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ProfileList) { + + Profile = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_NETWORK_PROFILE, + Link, WIFI_MGR_PROFILE_SIGNATURE); + + WifiMgrCleanProfileSecrets (Profile); + + if (Profile->Network.AKMSuite != NULL) { + FreePool(Profile->Network.AKMSuite); + } + + if (Profile->Network.CipherSuite != NULL) { + FreePool(Profile->Network.CipherSuite); + } + + FreePool (Profile); + } +} + +/** + Free user configured hidden network list. + + @param[in] HiddenList The hidden network list to be freed. + +**/ +VOID +WifiMgrFreeHiddenList ( + IN LIST_ENTRY *HiddenList + ) +{ + WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + if (HiddenList == NULL) { + return; + } + + NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, HiddenList) { + + HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, + Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); + FreePool (HiddenNetwork); + } +} + + +/** + Free the resources of a config token. + + @param[in] ConfigToken The config token to be freed. +**/ +VOID +WifiMgrFreeToken ( + IN WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken + ) +{ + EFI_80211_GET_NETWORKS_RESULT *Result; + + if (ConfigToken == NULL) { + return; + } + + switch (ConfigToken->Type) { + + case TokenTypeGetNetworksToken: + + if (ConfigToken->Token.GetNetworksToken != NULL) { + + gBS->CloseEvent (ConfigToken->Token.GetNetworksToken->Event); + if (ConfigToken->Token.GetNetworksToken->Data != NULL) { + FreePool(ConfigToken->Token.GetNetworksToken->Data); + } + + Result = ConfigToken->Token.GetNetworksToken->Result; + if (Result != NULL) { + FreePool (Result); + } + + FreePool(ConfigToken->Token.GetNetworksToken); + } + + FreePool (ConfigToken); + break; + + case TokenTypeConnectNetworkToken: + + if (ConfigToken->Token.ConnectNetworkToken != NULL) { + + gBS->CloseEvent (ConfigToken->Token.ConnectNetworkToken->Event); + if (ConfigToken->Token.ConnectNetworkToken->Data != NULL) { + FreePool(ConfigToken->Token.ConnectNetworkToken->Data); + } + FreePool(ConfigToken->Token.ConnectNetworkToken); + } + FreePool (ConfigToken); + break; + + case TokenTypeDisconnectNetworkToken: + + if (ConfigToken->Token.DisconnectNetworkToken != NULL) { + + FreePool(ConfigToken->Token.DisconnectNetworkToken); + } + + FreePool (ConfigToken); + break; + + default : + break; + } +} diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h new file mode 100644 index 00000000..88d6a7ff --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrMisc.h @@ -0,0 +1,262 @@ +/** @file + The Miscellaneous Routines for WiFi Connection Manager. + + Copyright (c) 2019, Intel Corporation. All rights reserved.<BR> + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __EFI_WIFI_MGR_MISC_H__ +#define __EFI_WIFI_MGR_MISC_H__ + +/** + Empty function for event process function. + + @param[in] Event The Event needs to be processed + @param[in] Context The context of the event + +**/ +VOID +EFIAPI +WifiMgrInternalEmptyFunction ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Convert the mac address into a hexadecimal encoded ":" seperated string. + + @param[in] Mac The mac address + @param[in] StrSize The size, in bytes, of the output buffer specified by Str + @param[out] Str The storage to return the mac string + +**/ +VOID +WifiMgrMacAddrToStr ( + IN EFI_80211_MAC_ADDRESS *Mac, + IN UINT32 StrSize, + OUT CHAR16 *Str + ); + +/** + Read private key file to buffer. + + @param[in] FileContext The file context of private key file. + @param[out] PrivateKeyDataAddr The buffer address to restore private key file, should be + freed by caller. + @param[out] PrivateKeyDataSize The size of read private key file. + + @retval EFI_SUCCESS Successfully read the private key file. + @retval EFI_INVALID_PARAMETER One or more of the parameters is invalid. + +**/ +EFI_STATUS +WifiMgrReadFileToBuffer ( + IN WIFI_MGR_FILE_CONTEXT *FileContext, + OUT VOID **PrivateKeyDataAddr, + OUT UINTN *PrivateKeyDataSize + ); + + +/** + Get the Nic data by the NicIndex. + + @param[in] Private The pointer to the global private data structure. + @param[in] NicIndex The index indicates the position of wireless NIC. + + @return Pointer to the Nic data, or NULL if not found. + +**/ +WIFI_MGR_DEVICE_DATA * +WifiMgrGetNicByIndex ( + IN WIFI_MGR_PRIVATE_DATA *Private, + IN UINT32 NicIndex + ); + +/** + Find a network profile through its' SSId and securit type, and the SSId is an unicode string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByUnicodeSSId ( + IN CHAR16 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ); + +/** + Find a network profile through its' SSId and securit type, and the SSId is an ascii string. + + @param[in] SSId The target network's SSId. + @param[in] SecurityType The target network's security type. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByAsciiSSId ( + IN CHAR8 *SSId, + IN UINT8 SecurityType, + IN LIST_ENTRY *ProfileList + ); + +/** + Find a network profile through its' profile index. + + @param[in] ProfileIndex The target network's profile index. + @param[in] ProfileList The profile list on a Nic. + + @return Pointer to a network profile, or NULL if not found. + +**/ +WIFI_MGR_NETWORK_PROFILE * +WifiMgrGetProfileByProfileIndex ( + IN UINT32 ProfileIndex, + IN LIST_ENTRY *ProfileList + ); + +/** + To test if the AKMSuite is in supported AKMSuite list. + + @param[in] SupportedAKMSuiteCount The count of the supported AKMSuites. + @param[in] SupportedAKMSuiteList The supported AKMSuite list. + @param[in] AKMSuite The AKMSuite to be tested. + + @return True if this AKMSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportAKMSuite ( + IN UINT16 SupportedAKMSuiteCount, + IN UINT32 *SupportedAKMSuiteList, + IN UINT32 *AKMSuite + ); + +/** + To check if the CipherSuite is in supported CipherSuite list. + + @param[in] SupportedCipherSuiteCount The count of the supported CipherSuites. + @param[in] SupportedCipherSuiteList The supported CipherSuite list. + @param[in] CipherSuite The CipherSuite to be tested. + + @return True if this CipherSuite is supported, or False if not. + +**/ +BOOLEAN +WifiMgrSupportCipherSuite ( + IN UINT16 SupportedCipherSuiteCount, + IN UINT32 *SupportedCipherSuiteList, + IN UINT32 *CipherSuite + ); + +/** + Check an AKM suite list and a Cipher suite list to see if one or more AKM suites or Cipher suites + are supported and find the matchable security type. + + @param[in] AKMList The target AKM suite list to be checked. + @param[in] CipherList The target Cipher suite list to be checked + @param[in] Nic The Nic to operate, contains the supported AKMSuite list + and supported CipherSuite list + @param[out] SecurityType To identify a security type from the AKM suite list and + Cipher suite list + @param[out] AKMSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + @param[out] CipherSuiteSupported To identify if this security type is supported. If it is + NULL, overcome this field + + @retval EFI_SUCCESS This operation has completed successfully. + @retval EFI_INVALID_PARAMETER No Nic found or the suite list is null. + +**/ +EFI_STATUS +WifiMgrCheckRSN ( + IN EFI_80211_AKM_SUITE_SELECTOR *AKMList, + IN EFI_80211_CIPHER_SUITE_SELECTOR *CipherList, + IN WIFI_MGR_DEVICE_DATA *Nic, + OUT UINT8 *SecurityType, + OUT BOOLEAN *AKMSuiteSupported, + OUT BOOLEAN *CipherSuiteSupported + ); + +/** + To get the security type for a certain AKMSuite and CipherSuite. + + @param[in] AKMSuite An certain AKMSuite. + @param[in] CipherSuite An certain CipherSuite. + + @return a security type if found, or SECURITY_TYPE_UNKNOWN. + +**/ +UINT8 +WifiMgrGetSecurityType ( + IN UINT32 *AKMSuite, + IN UINT32 *CipherSuite + ); + +/** + Get supported AKMSuites and CipherSuites from supplicant. + + @param[in] Nic The Nic to operate. + + @retval EFI_SUCCESS Get the supported suite list successfully. + @retval EFI_INVALID_PARAMETER No Nic found or supplicant is NULL. + +**/ +EFI_STATUS +WifiMgrGetSupportedSuites ( + IN WIFI_MGR_DEVICE_DATA *Nic + ); + +/** + Clean secrets from a network profile. + + @param[in] Profile The profile to be cleanned. + +**/ +VOID +WifiMgrCleanProfileSecrets ( + IN WIFI_MGR_NETWORK_PROFILE *Profile + ); + +/** + Free all network profiles in a profile list. + + @param[in] ProfileList The profile list to be freed. + +**/ +VOID +WifiMgrFreeProfileList ( + IN LIST_ENTRY *ProfileList + ); + +/** + Free user configured hidden network list. + + @param[in] HiddenList The hidden network list to be freed. + +**/ +VOID +WifiMgrFreeHiddenList ( + IN LIST_ENTRY *HiddenList + ); + +/** + Free the resources of a config token. + + @param[in] ConfigToken The config token to be freed. + +**/ +VOID +WifiMgrFreeToken ( + IN WIFI_MGR_MAC_CONFIG_TOKEN *ConfigToken + ); + +#endif |