summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Zemczak <sil2100@vexillium.org>2020-03-20 10:27:35 +0100
committerGitHub <noreply@github.com>2020-03-20 10:27:35 +0100
commit2427ab267b24daa3504345be4ee6be7f286056a3 (patch)
tree4b0970d11ee0bbec59c81632ce139d985cbe9ae1
parent261c379619b2128f62f8e8ae5d974fcf35677386 (diff)
Fix quotation of WPA PSK 64 hex-digit keys for networkd (#120)
* Fix quotation of WPA PSK hex passthrough for networkd when supplied with a 64 hex-digit string * Typo, was supposed to be 63 Co-authored-by: Łukasz 'sil2100' Zemczak <lukasz.zemczak@canonical.com>
-rw-r--r--src/networkd.c27
-rw-r--r--tests/generator/test_auth.py61
-rw-r--r--tests/generator/test_wifis.py26
3 files changed, 93 insertions, 21 deletions
diff --git a/src/networkd.c b/src/networkd.c
index a91a329..7555db3 100644
--- a/src/networkd.c
+++ b/src/networkd.c
@@ -16,7 +16,9 @@
*/
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
+#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
@@ -667,7 +669,7 @@ write_rules_file(net_definition* def, const char* rootdir)
}
static void
-append_wpa_auth_conf(GString* s, const authentication_settings* auth)
+append_wpa_auth_conf(GString* s, const authentication_settings* auth, const char* id)
{
switch (auth->key_management) {
case KEY_MANAGEMENT_NONE:
@@ -712,7 +714,24 @@ append_wpa_auth_conf(GString* s, const authentication_settings* auth)
}
if (auth->password) {
if (auth->key_management == KEY_MANAGEMENT_WPA_PSK) {
- g_string_append_printf(s, " psk=\"%s\"\n", auth->password);
+ size_t len = strlen(auth->password);
+ if (len == 64) {
+ /* must be a hex-digit key representation */
+ for (unsigned i = 0; i < 64; ++i)
+ if (!isxdigit(auth->password[i])) {
+ g_fprintf(stderr, "ERROR: %s: PSK length of 64 is only supported for hex-digit representation\n", id);
+ exit(1);
+ }
+ /* this is required to be unquoted */
+ g_string_append_printf(s, " psk=%s\n", auth->password);
+ } else if (len < 8 || len > 63) {
+ /* per wpa_supplicant spec, passphrase needs to be between 8
+ and 63 characters */
+ g_fprintf(stderr, "ERROR: %s: ASCII passphrase must be between 8 and 63 characters (inclusive)\n", id);
+ exit(1);
+ } else {
+ g_string_append_printf(s, " psk=\"%s\"\n", auth->password);
+ }
} else {
if (strncmp(auth->password, "hash:", 5) == 0) {
g_string_append_printf(s, " password=%s\n", auth->password);
@@ -802,7 +821,7 @@ write_wpa_conf(net_definition* def, const char* rootdir)
/* wifi auth trumps netdef auth */
if (ap->has_auth) {
- append_wpa_auth_conf(s, &ap->auth);
+ append_wpa_auth_conf(s, &ap->auth, ap->ssid);
}
else {
g_string_append(s, " key_mgmt=NONE\n");
@@ -813,7 +832,7 @@ write_wpa_conf(net_definition* def, const char* rootdir)
else {
/* wired 802.1x auth or similar */
g_string_append(s, "network={\n");
- append_wpa_auth_conf(s, &def->auth);
+ append_wpa_auth_conf(s, &def->auth, def->id);
g_string_append(s, "}\n");
}
diff --git a/tests/generator/test_auth.py b/tests/generator/test_auth.py
index 776bfcb..f35f3f8 100644
--- a/tests/generator/test_auth.py
+++ b/tests/generator/test_auth.py
@@ -31,11 +31,17 @@ class TestNetworkd(TestBase):
wl0:
access-points:
"Joe's Home":
- password: "s3kr1t"
+ password: "s0s3kr1t"
"Luke's Home":
auth:
key-management: psk
password: "4lsos3kr1t"
+ "BobsHome":
+ password: "e03ce667c87bc81ca968d9120ca37f89eb09aec3c55b80386e5d772efd6b926e"
+ "BillsHome":
+ auth:
+ key-management: psk
+ password: "db3b0acf5653aeaddd5fe034fb9f07175b2864f847b005aaa2f09182d9411b04"
workplace:
auth:
key-management: eap
@@ -102,6 +108,20 @@ network={
''', new_config)
self.assertIn('''
network={
+ ssid="BobsHome"
+ key_mgmt=WPA-PSK
+ psk=e03ce667c87bc81ca968d9120ca37f89eb09aec3c55b80386e5d772efd6b926e
+}
+''', new_config)
+ self.assertIn('''
+network={
+ ssid="BillsHome"
+ key_mgmt=WPA-PSK
+ psk=db3b0acf5653aeaddd5fe034fb9f07175b2864f847b005aaa2f09182d9411b04
+}
+''', new_config)
+ self.assertIn('''
+network={
ssid="workplace2"
key_mgmt=WPA-EAP
eap=PEAP
@@ -153,7 +173,7 @@ network={
network={
ssid="Joe's Home"
key_mgmt=WPA-PSK
- psk="s3kr1t"
+ psk="s0s3kr1t"
}
''', new_config)
self.assertEqual(stat.S_IMODE(os.fstat(f.fileno()).st_mode), 0o600)
@@ -219,7 +239,7 @@ class TestNetworkManager(TestBase):
wl0:
access-points:
"Joe's Home":
- password: "s3kr1t"
+ password: "s0s3kr1t"
"Luke's Home":
auth:
key-management: psk
@@ -286,7 +306,7 @@ mode=infrastructure
[wifi-security]
key-mgmt=wpa-psk
-psk=s3kr1t
+psk=s0s3kr1t
''',
'wl0-Luke%27s%20Home': '''[connection]
id=netplan-wl0-Luke's Home
@@ -524,3 +544,36 @@ class TestConfigErrors(TestBase):
auth:
method: bogus''', expect_fail=True)
self.assertIn("unknown EAP method 'bogus'", err)
+
+ def test_auth_networkd_wifi_psk_too_big(self):
+ err = self.generate('''network:
+ version: 2
+ wifis:
+ wl0:
+ access-points:
+ "Joe's Home":
+ password: "LoremipsumdolorsitametconsecteturadipiscingelitCrastemporvelitnunc"
+ dhcp4: yes''', expect_fail=True)
+ self.assertIn("ASCII passphrase must be between 8 and 63 characters (inclusive)", err)
+
+ def test_auth_networkd_wifi_psk_too_small(self):
+ err = self.generate('''network:
+ version: 2
+ wifis:
+ wl0:
+ access-points:
+ "Joe's Home":
+ password: "p4ss"
+ dhcp4: yes''', expect_fail=True)
+ self.assertIn("ASCII passphrase must be between 8 and 63 characters (inclusive)", err)
+
+ def test_auth_networkd_wifi_psk_64_non_hexdigit(self):
+ err = self.generate('''network:
+ version: 2
+ wifis:
+ wl0:
+ access-points:
+ "Joe's Home":
+ password: "LoremipsumdolorsitametconsecteturadipiscingelitCrastemporvelitnu"
+ dhcp4: yes''', expect_fail=True)
+ self.assertIn("PSK length of 64 is only supported for hex-digit representation", err)
diff --git a/tests/generator/test_wifis.py b/tests/generator/test_wifis.py
index 2182450..3e38be9 100644
--- a/tests/generator/test_wifis.py
+++ b/tests/generator/test_wifis.py
@@ -31,9 +31,9 @@ class TestNetworkd(TestBase):
wl0:
access-points:
"Joe's Home":
- password: "s3kr1t"
+ password: "s0s3kr1t"
workplace:
- password: "c0mpany"
+ password: "c0mpany1"
peer2peer:
mode: adhoc
dhcp4: yes''')
@@ -58,14 +58,14 @@ network={
network={
ssid="workplace"
key_mgmt=WPA-PSK
- psk="c0mpany"
+ psk="c0mpany1"
}
''', new_config)
self.assertIn('''
network={
ssid="Joe's Home"
key_mgmt=WPA-PSK
- psk="s3kr1t"
+ psk="s0s3kr1t"
}
''', new_config)
self.assertEqual(stat.S_IMODE(os.fstat(f.fileno()).st_mode), 0o600)
@@ -81,7 +81,7 @@ network={
wl0:
access-points:
workplace:
- password: "c0mpany"
+ password: "c0mpany1"
dhcp4: yes
routes:
- to: 10.10.10.0/24
@@ -117,7 +117,7 @@ unmanaged-devices+=interface-name:wl0,''')
driver: foo
access-points:
workplace:
- password: "c0mpany"
+ password: "c0mpany1"
dhcp4: yes''', expect_fail=True)
self.assertIn('networkd backend does not support wifi with match:', err)
@@ -128,7 +128,7 @@ unmanaged-devices+=interface-name:wl0,''')
wl0:
access-points:
workplace:
- password: "c0mpany"
+ password: "c0mpany1"
mode: ap
dhcp4: yes''', expect_fail=True)
self.assertIn('networkd does not support wifi in access point mode', err)
@@ -144,9 +144,9 @@ class TestNetworkManager(TestBase):
wl0:
access-points:
"Joe's Home":
- password: "s3kr1t"
+ password: "s0s3kr1t"
workplace:
- password: "c0mpany"
+ password: "c0mpany1"
dhcp4: yes''')
self.assert_nm({'wl0-Joe%27s%20Home': '''[connection]
@@ -169,7 +169,7 @@ mode=infrastructure
[wifi-security]
key-mgmt=wpa-psk
-psk=s3kr1t
+psk=s0s3kr1t
''',
'wl0-workplace': '''[connection]
id=netplan-wl0-workplace
@@ -191,7 +191,7 @@ mode=infrastructure
[wifi-security]
key-mgmt=wpa-psk
-psk=c0mpany
+psk=c0mpany1
'''})
self.assert_networkd({})
self.assert_nm_udev(None)
@@ -265,7 +265,7 @@ mode=infrastructure
access-points:
homenet:
mode: ap
- password: s3cret''')
+ password: s0s3cret''')
self.assert_nm({'wl0-homenet': '''[connection]
id=netplan-wl0-homenet
@@ -287,7 +287,7 @@ mode=ap
[wifi-security]
key-mgmt=wpa-psk
-psk=s3cret
+psk=s0s3cret
'''})
self.assert_networkd({})
self.assert_nm_udev(None)