Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion openwisp_radius/api/freeradius_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ def _check_client_ip_and_return(self, request, uuid):

for ip in ip_list:
try:
if ipaddress.ip_address(client_ip) in ipaddress.ip_network(ip):
if ipaddress.ip_address(client_ip) in ipaddress.ip_network(
(ip or "").strip(), strict=False
):
return (AnonymousUser(), uuid)
except ValueError:
invalid_addr_message = _(
Expand Down
11 changes: 8 additions & 3 deletions openwisp_radius/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1338,8 +1338,11 @@ def __str__(self):
@property
def freeradius_allowed_hosts_list(self):
addresses = []
if self.freeradius_allowed_hosts:
addresses = self.freeradius_allowed_hosts.split(",")
addresses = [
(ip or "").strip()
for ip in (self.freeradius_allowed_hosts or "").split(",")
if (ip or "").strip()
]
return addresses

@property
Expand Down Expand Up @@ -1383,7 +1386,9 @@ def _clean_freeradius_allowed_hosts(self):
else:
try:
for ip_address in allowed_hosts_set:
ipaddress.ip_network(ip_address)
ip_str = (ip_address or "").strip()
if ip_str:
ipaddress.ip_network(ip_str, strict=False)
except ValueError:
raise ValidationError(
{
Expand Down
61 changes: 61 additions & 0 deletions openwisp_radius/tests/test_api/test_freeradius_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2385,6 +2385,67 @@ def test_ip_from_radsetting_valid(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, _AUTH_TYPE_ACCEPT_RESPONSE)

def test_ip_from_radsetting_cidr_range_valid(self):
with mock.patch(self.freeradius_hosts_path, []):
radsetting = OrganizationRadiusSettings.objects.get(
organization=self._get_org()
)
radsetting.freeradius_allowed_hosts = "172.18.0.0/16"
radsetting.save()

with mock.patch(
"openwisp_radius.api.freeradius_views.get_client_ip",
return_value=("172.18.0.10", True),
):
response = self.client.post(reverse("radius:authorize"), self.params)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, _AUTH_TYPE_ACCEPT_RESPONSE)

def test_ip_from_radsetting_spaces_and_host_bits_valid(self):
org = self._get_org()
with mock.patch(self.freeradius_hosts_path, []):
radsetting = OrganizationRadiusSettings.objects.get(organization=org)

radsetting.freeradius_allowed_hosts = "127.0.0.1, 172.18.0.5/16"
radsetting.save()

self.assertEqual(
cache.get(f"ip-{org.pk}"),
["127.0.0.1", "172.18.0.5/16"],
)

with mock.patch(
"openwisp_radius.api.freeradius_views.get_client_ip",
return_value=("172.18.0.10", True),
):
response = self.client.post(reverse("radius:authorize"), self.params)

self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, _AUTH_TYPE_ACCEPT_RESPONSE)

@capture_any_output()
def test_ip_outside_cidr_range_rejected(self):
with mock.patch(self.freeradius_hosts_path, []):
radsetting = OrganizationRadiusSettings.objects.get(
organization=self._get_org()
)
radsetting.freeradius_allowed_hosts = "172.18.0.0/16"
radsetting.save()

with mock.patch(
"openwisp_radius.api.freeradius_views.get_client_ip",
return_value=("10.0.0.5", True),
):
response = self.client.post(reverse("radius:authorize"), self.params)

self.assertEqual(response.status_code, 403)
self.assertEqual(
response.data["detail"],
"Request rejected: Client IP address (10.0.0.5) is not in "
"the list of IP addresses allowed to consume the freeradius API.",
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

def test_ip_from_setting_valid(self):
response = self.client.post(reverse("radius:authorize"), self.params)
self.assertEqual(response.status_code, 200)
Expand Down
Loading