Skip to content

Commit

Permalink
auth: add support for LEAP and EAP-PWD
Browse files Browse the repository at this point in the history
This changes add support for the LEAP and PWD EAP authentication methods
for NetworkManager, wpa_supplicant (networkd) and the keyfile parser.

Using these method through the NM GUI is causing problems because
libnetplan will generate a broken keyfile. See LP: #2038811

Note that the NM GUI supports more methods not recognized by netplan and
we probably should also implement them later.
  • Loading branch information
daniloegea committed Oct 11, 2023
1 parent 1758948 commit 62a2d52
Show file tree
Hide file tree
Showing 9 changed files with 246 additions and 1 deletion.
3 changes: 2 additions & 1 deletion doc/netplan-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,8 @@ 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), `leap` (Lightweight EAP), `pwd` (EAP Password)
> and `ttls` (Tunneled TLS).

- **identity** (scalar)

Expand Down
2 changes: 2 additions & 0 deletions src/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ typedef enum {
NETPLAN_AUTH_EAP_TLS,
NETPLAN_AUTH_EAP_PEAP,
NETPLAN_AUTH_EAP_TTLS,
NETPLAN_AUTH_EAP_LEAP,
NETPLAN_AUTH_EAP_PWD,
NETPLAN_AUTH_EAP_METHOD_MAX,
} NetplanAuthEAPMethod;

Expand Down
2 changes: 2 additions & 0 deletions src/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ netplan_auth_eap_method_to_str[NETPLAN_AUTH_EAP_METHOD_MAX] = {
[NETPLAN_AUTH_EAP_TLS] = "tls",
[NETPLAN_AUTH_EAP_PEAP] = "peap",
[NETPLAN_AUTH_EAP_TTLS] = "ttls",
[NETPLAN_AUTH_EAP_LEAP] = "leap",
[NETPLAN_AUTH_EAP_PWD] = "pwd",
};

static const char* const
Expand Down
8 changes: 8 additions & 0 deletions src/networkd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,14 @@ append_wpa_auth_conf(GString* s, const NetplanAuthenticationSettings* auth, cons
g_string_append(s, " eap=TTLS\n");
break;

case NETPLAN_AUTH_EAP_LEAP:
g_string_append(s, " eap=LEAP\n");
break;

case NETPLAN_AUTH_EAP_PWD:
g_string_append(s, " eap=PWD\n");
break;

default: break; // LCOV_EXCL_LINE
}

Expand Down
6 changes: 6 additions & 0 deletions src/nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,12 @@ write_dot1x_auth_parameters(const NetplanAuthenticationSettings* auth, GKeyFile
case NETPLAN_AUTH_EAP_TTLS:
g_key_file_set_string(kf, "802-1x", "eap", "ttls");
break;
case NETPLAN_AUTH_EAP_LEAP:
g_key_file_set_string(kf, "802-1x", "eap", "leap");
break;
case NETPLAN_AUTH_EAP_PWD:
g_key_file_set_string(kf, "802-1x", "eap", "pwd");
break;
default: break; // LCOV_EXCL_LINE
}

Expand Down
4 changes: 4 additions & 0 deletions src/parse-nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ parse_dot1x_auth(GKeyFile* kf, NetplanAuthenticationSettings* auth)
auth->eap_method = NETPLAN_AUTH_EAP_PEAP;
} else if (g_strcmp0(first_method, "ttls") == 0) {
auth->eap_method = NETPLAN_AUTH_EAP_TTLS;
} else if (g_strcmp0(first_method, "leap") == 0) {
auth->eap_method = NETPLAN_AUTH_EAP_LEAP;
} else if (g_strcmp0(first_method, "pwd") == 0) {
auth->eap_method = NETPLAN_AUTH_EAP_PWD;
}

/* If "method" (which is a list separated by ";") has more than one value,
Expand Down
4 changes: 4 additions & 0 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,10 @@ handle_auth_method(NetplanParser* npp, yaml_node_t* node, __unused const void* _
auth->eap_method = NETPLAN_AUTH_EAP_PEAP;
else if (strcmp(scalar(node), "ttls") == 0)
auth->eap_method = NETPLAN_AUTH_EAP_TTLS;
else if (strcmp(scalar(node), "leap") == 0)
auth->eap_method = NETPLAN_AUTH_EAP_LEAP;
else if (strcmp(scalar(node), "pwd") == 0)
auth->eap_method = NETPLAN_AUTH_EAP_PWD;
else
return yaml_error(npp, node, error, "unknown EAP method '%s'", scalar(node));
return TRUE;
Expand Down
124 changes: 124 additions & 0 deletions tests/generator/test_wifis.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,54 @@ def test_wifi_wpa3_enterprise_eap_suite_b_192(self):
}
""")

def test_wifi_ieee8021x_eap_leap(self):
self.generate('''network:
version: 2
wifis:
wl0:
access-points:
homenet:
auth:
key-management: 802.1x
method: leap
identity: some-id
password: "********"''')

self.assert_wpa_supplicant("wl0", """ctrl_interface=/run/wpa_supplicant
network={
ssid="homenet"
key_mgmt=IEEE8021X
eap=LEAP
identity="some-id"
password="********"
}
""")

def test_wifi_ieee8021x_eap_pwd(self):
self.generate('''network:
version: 2
wifis:
wl0:
access-points:
homenet:
auth:
key-management: 802.1x
method: pwd
identity: some-id
password: "********"''')

self.assert_wpa_supplicant("wl0", """ctrl_interface=/run/wpa_supplicant
network={
ssid="homenet"
key_mgmt=IEEE8021X
eap=PWD
identity="some-id"
password="********"
}
""")


class TestNetworkManager(TestBase):

Expand Down Expand Up @@ -873,6 +921,82 @@ def test_wifi_wpa3_enterprise_eap_suite_b_192(self):
client-cert=/etc/ssl/cust-crt.pem
private-key=/etc/ssl/cust-key.pem
private-key-password=**********
'''})

def test_wifi_ieee8021x_leap(self):
self.generate('''network:
version: 2
renderer: NetworkManager
wifis:
wl0:
access-points:
homenet:
auth:
key-management: 802.1x
method: leap
identity: "some-id"
password: "**********"''')

self.assert_nm({'wl0-homenet': '''[connection]
id=netplan-wl0-homenet
type=wifi
interface-name=wl0
[ipv4]
method=link-local
[ipv6]
method=ignore
[wifi]
ssid=homenet
mode=infrastructure
[wifi-security]
key-mgmt=ieee8021x
[802-1x]
eap=leap
identity=some-id
password=**********
'''})

def test_wifi_ieee8021x_pwd(self):
self.generate('''network:
version: 2
renderer: NetworkManager
wifis:
wl0:
access-points:
homenet:
auth:
key-management: 802.1x
method: pwd
identity: "some-id"
password: "**********"''')

self.assert_nm({'wl0-homenet': '''[connection]
id=netplan-wl0-homenet
type=wifi
interface-name=wl0
[ipv4]
method=link-local
[ipv6]
method=ignore
[wifi]
ssid=homenet
mode=infrastructure
[wifi-security]
key-mgmt=ieee8021x
[802-1x]
eap=pwd
identity=some-id
password=**********
'''})

def test_wifi_wowlan(self):
Expand Down
94 changes: 94 additions & 0 deletions tests/parser/test_keyfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,100 @@ def test_keyfile_type_wifi_eap_tls(self):
def test_keyfile_type_wifi_eap_ttls(self):
self._template_keyfile_type_wifi_eap('ttls')

def test_keyfile_type_wifi_eap_leap(self):
self.generate_from_keyfile('''[connection]
type=wifi
uuid={}
permissions=
id=myid with spaces
interface-name=eth0
[wifi]
ssid=SOME-SSID
mode=infrastructure
[wifi-security]
key-mgmt=ieee8021x
[802-1x]
eap=leap
identity=some-id
password=v3rys3cr3t!
[ipv4]
method=auto'''.format(UUID))
self.assert_netplan({UUID: '''network:
version: 2
wifis:
NM-{}:
renderer: NetworkManager
match:
name: "eth0"
dhcp4: true
access-points:
"SOME-SSID":
auth:
key-management: "802.1x"
method: "leap"
identity: "some-id"
password: "v3rys3cr3t!"
networkmanager:
uuid: "{}"
name: "myid with spaces"
passthrough:
connection.permissions: ""
networkmanager:
uuid: "{}"
name: "myid with spaces"
'''.format(UUID, UUID, UUID)})

def test_keyfile_type_wifi_eap_pwd(self):
self.generate_from_keyfile('''[connection]
type=wifi
uuid={}
permissions=
id=myid with spaces
interface-name=eth0
[wifi]
ssid=SOME-SSID
mode=infrastructure
[wifi-security]
key-mgmt=ieee8021x
[802-1x]
eap=pwd
identity=some-id
password=v3rys3cr3t!
[ipv4]
method=auto'''.format(UUID))
self.assert_netplan({UUID: '''network:
version: 2
wifis:
NM-{}:
renderer: NetworkManager
match:
name: "eth0"
dhcp4: true
access-points:
"SOME-SSID":
auth:
key-management: "802.1x"
method: "pwd"
identity: "some-id"
password: "v3rys3cr3t!"
networkmanager:
uuid: "{}"
name: "myid with spaces"
passthrough:
connection.permissions: ""
networkmanager:
uuid: "{}"
name: "myid with spaces"
'''.format(UUID, UUID, UUID)})

def _template_keyfile_type_wifi(self, nd_mode, nm_mode):
self.generate_from_keyfile('''[connection]
type=wifi
Expand Down

0 comments on commit 62a2d52

Please sign in to comment.