Skip to content

Commit

Permalink
netplan: add support for WPA3-Enterprise
Browse files Browse the repository at this point in the history
PMF (Protected Management Frames) is required by WPA3 and was
already implicitly set to "required" for WPA3-Personal (via SAE).

Network Manager will enable different EAP methods simultaneously when we
set it to "eap", such as WPA-EAP and WPA-EAP-SHA256. NM doesn't allow
the user to set the method as "eap-sha256" only.

These changes add two new EAP methods to Netplan: "eap-sha256" and
"eap-suite-b-192". They are both used with WPA3-Enterprise.

PMF is mandatory when using "eap-suite-b-192" so it's implicitly set to
"required". It's implicitly set to "optional" when eap-sha256 is used.
  • Loading branch information
daniloegea committed Aug 23, 2023
1 parent 3e6783f commit d73b3a9
Show file tree
Hide file tree
Showing 11 changed files with 423 additions and 11 deletions.
7 changes: 4 additions & 3 deletions doc/netplan-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,9 @@ interfaces, as well as individual wifi networks, by means of the `auth` block.

> The supported key management modes are `none` (no key management);
> `psk` (WPA with pre-shared key, common for home wifi); `eap` (WPA
> with EAP, common for enterprise wifi); `sae` (used by WPA3); and `802.1x`
> (used primarily for wired Ethernet connections).
> with EAP, common for enterprise wifi); `eap-sha256` (used with WPA3-Enterprise);
> `eap-suite-b-192` (used with WPA3-Enterprise); `sae` (used by WPA3);
> and `802.1x` (used primarily for wired Ethernet connections).

- **password** (scalar)

Expand All @@ -863,7 +864,7 @@ interfaces, as well as individual wifi networks, by means of the `auth` block.
- **method** (scalar)

> The EAP method to use. The supported EAP methods are `tls` (TLS),
> `peap` (Protected EAP), and `ttls` (Tunneled TLS).
> `peap` (Protected EAP), and `ttls` (Tunneled TLS).

- **identity** (scalar)

Expand Down
26 changes: 26 additions & 0 deletions examples/wpa3_enterprise.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
network:
version: 2
wifis:
wl0:
dhcp4: yes
access-points:
university:
auth:
key-management: eap-sha256
method: tls
anonymous-identity: "@cust.example.com"
identity: "[email protected]"
ca-certificate: /etc/ssl/cust-cacrt.pem
client-certificate: /etc/ssl/cust-crt.pem
client-key: /etc/ssl/cust-key.pem
client-key-password: "d3cryptPr1v4t3K3y"
enterprise:
auth:
key-management: eap-suite-b-192
method: tls
anonymous-identity: "@cust.example.com"
identity: "[email protected]"
ca-certificate: /etc/ssl/cust-cacrt.pem
client-certificate: /etc/ssl/cust-crt.pem
client-key: /etc/ssl/cust-key.pem
client-key-password: "d3cryptPr1v4t3K3y"
10 changes: 10 additions & 0 deletions src/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ typedef enum {
NETPLAN_AUTH_KEY_MANAGEMENT_NONE,
NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK,
NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP,
NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256,
NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192,
NETPLAN_AUTH_KEY_MANAGEMENT_8021X,
NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE,
NETPLAN_AUTH_KEY_MANAGEMENT_MAX,
Expand All @@ -119,9 +121,17 @@ typedef enum {
NETPLAN_AUTH_EAP_METHOD_MAX,
} NetplanAuthEAPMethod;

typedef enum {
NETPLAN_AUTH_PMF_MODE_NONE,
NETPLAN_AUTH_PMF_MODE_DISABLED,
NETPLAN_AUTH_PMF_MODE_OPTIONAL,
NETPLAN_AUTH_PMF_MODE_REQUIRED,
} NetplanAuthPMFMode;

typedef struct authentication_settings {
NetplanAuthKeyManagementType key_management;
NetplanAuthEAPMethod eap_method;
NetplanAuthPMFMode pmf_mode;
char* identity;
char* anonymous_identity;
char* password;
Expand Down
2 changes: 2 additions & 0 deletions src/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ netplan_auth_key_management_type_to_str[NETPLAN_AUTH_KEY_MANAGEMENT_MAX] = {
[NETPLAN_AUTH_KEY_MANAGEMENT_NONE] = "none",
[NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK] = "psk",
[NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP] = "eap",
[NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256] = "eap-sha256",
[NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192] = "eap-suite-b-192",
[NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE] = "sae",
[NETPLAN_AUTH_KEY_MANAGEMENT_8021X] = "802.1x",
};
Expand Down
27 changes: 22 additions & 5 deletions src/networkd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1049,13 +1049,16 @@ append_wpa_auth_conf(GString* s, const NetplanAuthenticationSettings* auth, cons
g_string_append(s, " key_mgmt=WPA-EAP\n");
break;

case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256:
g_string_append(s, " key_mgmt=WPA-EAP WPA-EAP-SHA256\n");
break;

case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192:
g_string_append(s, " key_mgmt=WPA-EAP-SUITE-B-192\n");
break;

case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE:
/*
* SAE is used by WPA3 and Management Frame Protection
* (ieee80211w) is mandatory.
*/
g_string_append(s, " key_mgmt=SAE\n");
g_string_append(s, " ieee80211w=2\n");
break;

case NETPLAN_AUTH_KEY_MANAGEMENT_8021X:
Expand Down Expand Up @@ -1084,6 +1087,20 @@ append_wpa_auth_conf(GString* s, const NetplanAuthenticationSettings* auth, cons
default: break; // LCOV_EXCL_LINE
}

switch (auth->pmf_mode) {
case NETPLAN_AUTH_PMF_MODE_NONE:
case NETPLAN_AUTH_PMF_MODE_DISABLED:
break;

case NETPLAN_AUTH_PMF_MODE_OPTIONAL:
g_string_append(s, " ieee80211w=1\n");
break;

case NETPLAN_AUTH_PMF_MODE_REQUIRED:
g_string_append(s, " ieee80211w=2\n");
break;
}

if (auth->identity) {
g_string_append_printf(s, " identity=\"%s\"\n", auth->identity);
}
Expand Down
19 changes: 19 additions & 0 deletions src/nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,8 +447,13 @@ write_wifi_auth_parameters(const NetplanAuthenticationSettings* auth, GKeyFile *
g_key_file_set_string(kf, "wifi-security", "key-mgmt", "wpa-psk");
break;
case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP:
case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256:
/* NM uses "wpa-eap" to enable both EAP and EAP-SHA256 */
g_key_file_set_string(kf, "wifi-security", "key-mgmt", "wpa-eap");
break;
case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192:
g_key_file_set_string(kf, "wifi-security", "key-mgmt", "wpa-eap-suite-b-192");
break;
case NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE:
g_key_file_set_string(kf, "wifi-security", "key-mgmt", "sae");
break;
Expand All @@ -458,6 +463,20 @@ write_wifi_auth_parameters(const NetplanAuthenticationSettings* auth, GKeyFile *
default: break; // LCOV_EXCL_LINE
}

switch (auth->pmf_mode) {
case NETPLAN_AUTH_PMF_MODE_NONE:
case NETPLAN_AUTH_PMF_MODE_DISABLED:
break;

case NETPLAN_AUTH_PMF_MODE_OPTIONAL:
g_key_file_set_string(kf, "wifi-security", "pmf", "2");
break;

case NETPLAN_AUTH_PMF_MODE_REQUIRED:
g_key_file_set_string(kf, "wifi-security", "pmf", "3");
break;
}

if (auth->eap_method != NETPLAN_AUTH_EAP_NONE)
write_dot1x_auth_parameters(auth, kf);
else if (auth->password)
Expand Down
25 changes: 25 additions & 0 deletions src/parse-nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
g_autofree gchar* netdef_id = NULL;
ssize_t netdef_id_size = 0;
gchar *tmp_str = NULL;
gint pmf = 0;
NetplanNetDefinition* nd = NULL;
NetplanWifiAccessPoint* ap = NULL;
g_autoptr(GKeyFile) kf = g_key_file_new();
Expand Down Expand Up @@ -970,6 +971,10 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP;
ap->has_auth = TRUE;
_kf_clear_key(kf, "wifi-security", "key-mgmt");
} else if (tmp_str && g_strcmp0(tmp_str, "wpa-eap-suite-b-192") == 0) {
ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192;
ap->has_auth = TRUE;
_kf_clear_key(kf, "wifi-security", "key-mgmt");
} else if (tmp_str && g_strcmp0(tmp_str, "sae") == 0) {
ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE;
ap->has_auth = TRUE;
Expand All @@ -981,6 +986,26 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
}
g_free(tmp_str);

pmf = g_key_file_get_integer(kf, "wifi-security", "pmf", NULL);
switch (pmf) {
case 2:
ap->auth.pmf_mode = NETPLAN_AUTH_PMF_MODE_OPTIONAL;
_kf_clear_key(kf, "wifi-security", "pmf");
/* If pmf is set to 2 (optional) and the key management is EAP
* we set it to EAPSHA256 so the correct method is emitted in the YAML
*/
if (ap->auth.key_management == NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP)
ap->auth.key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256;
break;

case 3:
ap->auth.pmf_mode = NETPLAN_AUTH_PMF_MODE_REQUIRED;
_kf_clear_key(kf, "wifi-security", "pmf");
break;

default: break;
}

keyfile_handle_generic_str(kf, "wifi-security", "psk", &ap->auth.password);
if (ap->auth.password)
ap->has_auth = TRUE;
Expand Down
21 changes: 20 additions & 1 deletion src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -915,8 +915,27 @@ handle_auth_key_management(NetplanParser* npp, yaml_node_t* node, __unused const
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_PSK;
else if (strcmp(scalar(node), "eap") == 0)
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAP;
else if (strcmp(scalar(node), "sae") == 0)
else if (strcmp(scalar(node), "eap-sha256") == 0) {
/* WPA-EAP-SHA256 is commonly used with Protected Management Frames
* so let's set it as optional
*/
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSHA256;
auth->pmf_mode = NETPLAN_AUTH_PMF_MODE_OPTIONAL;
}
else if (strcmp(scalar(node), "eap-suite-b-192") == 0) {
/* Settings for WPA3-Enterprise for sensitive enterprise environments.
* Protected Management Frames (ieee80211w) is mandatory.
*/
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_EAPSUITE_B_192;
auth->pmf_mode = NETPLAN_AUTH_PMF_MODE_REQUIRED;
}
else if (strcmp(scalar(node), "sae") == 0) {
/* SAE is used by WPA3 and Protected Management Frames
* (ieee80211w) is mandatory.
*/
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_WPA_SAE;
auth->pmf_mode = NETPLAN_AUTH_PMF_MODE_REQUIRED;
}
else if (strcmp(scalar(node), "802.1x") == 0)
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_8021X;
else
Expand Down
1 change: 1 addition & 0 deletions src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ reset_auth_settings(NetplanAuthenticationSettings* auth)
FREE_AND_NULLIFY(auth->phase2_auth);
auth->key_management = NETPLAN_AUTH_KEY_MANAGEMENT_NONE;
auth->eap_method = NETPLAN_AUTH_EAP_NONE;
auth->pmf_mode = NETPLAN_AUTH_PMF_MODE_NONE;
}

void
Expand Down
Loading

0 comments on commit d73b3a9

Please sign in to comment.