mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
Merge pull request #30720 from yuwata/dhcp-server-address-verification
dhcp-server: several fixlets for address verification
This commit is contained in:
commit
09263532b6
@ -136,7 +136,7 @@ sd_dhcp_server_lease* dhcp_server_get_static_lease(sd_dhcp_server *server, const
|
||||
|
||||
static_lease = hashmap_get(server->static_leases_by_client_id, &req->client_id);
|
||||
if (static_lease)
|
||||
return static_lease;
|
||||
goto verify;
|
||||
|
||||
/* when no lease is found based on the client id fall back to chaddr */
|
||||
if (!client_id_data_size_is_valid(req->message->hlen))
|
||||
@ -145,7 +145,20 @@ sd_dhcp_server_lease* dhcp_server_get_static_lease(sd_dhcp_server *server, const
|
||||
if (sd_dhcp_client_id_set(&client_id, /* type = */ 1, req->message->chaddr, req->message->hlen) < 0)
|
||||
return NULL;
|
||||
|
||||
return hashmap_get(server->static_leases_by_client_id, &client_id);
|
||||
static_lease = hashmap_get(server->static_leases_by_client_id, &client_id);
|
||||
if (!static_lease)
|
||||
return NULL;
|
||||
|
||||
verify:
|
||||
/* Check if the address is in the same subnet. */
|
||||
if ((static_lease->address & server->netmask) != server->subnet)
|
||||
return NULL;
|
||||
|
||||
/* Check if the address is different from the server address. */
|
||||
if (static_lease->address == server->address)
|
||||
return NULL;
|
||||
|
||||
return static_lease;
|
||||
}
|
||||
|
||||
int sd_dhcp_server_set_static_lease(
|
||||
|
@ -87,13 +87,6 @@ int sd_dhcp_server_configure_pool(
|
||||
server->address = address->s_addr;
|
||||
server->netmask = netmask;
|
||||
server->subnet = address->s_addr & netmask;
|
||||
|
||||
/* Drop any leases associated with the old address range */
|
||||
hashmap_clear(server->bound_leases_by_address);
|
||||
hashmap_clear(server->bound_leases_by_client_id);
|
||||
|
||||
if (server->callback)
|
||||
server->callback(server, SD_DHCP_SERVER_EVENT_LEASE_CHANGED, server->callback_userdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1050,10 +1043,19 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
return 0;
|
||||
|
||||
/* for now pick a random free address from the pool */
|
||||
if (static_lease)
|
||||
if (static_lease) {
|
||||
if (existing_lease != hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(static_lease->address)))
|
||||
/* The address is already assigned to another host. Refusing. */
|
||||
return 0;
|
||||
|
||||
/* Found a matching static lease. */
|
||||
address = static_lease->address;
|
||||
else if (existing_lease)
|
||||
|
||||
} else if (existing_lease && address_is_in_pool(server, existing_lease->address))
|
||||
|
||||
/* If we previously assigned an address to the host, then reuse it. */
|
||||
address = existing_lease->address;
|
||||
|
||||
else {
|
||||
struct siphash state;
|
||||
uint64_t hash;
|
||||
@ -1151,30 +1153,24 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
|
||||
/* Silently ignore Rapid Commit option in REQUEST message. */
|
||||
req->rapid_commit = false;
|
||||
|
||||
/* disallow our own address */
|
||||
if (address == server->address)
|
||||
return 0;
|
||||
|
||||
if (static_lease) {
|
||||
/* Found a static lease for the client ID. */
|
||||
|
||||
if (static_lease->address != address)
|
||||
/* The client requested an address which is different from the static lease. Refuse. */
|
||||
/* The client requested an address which is different from the static lease. Refusing. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
if (existing_lease != hashmap_get(server->bound_leases_by_address, UINT32_TO_PTR(address)))
|
||||
/* The requested address is already assigned to another host. Refusing. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
/* Found a static lease for the client ID. */
|
||||
return server_ack_request(server, req, address);
|
||||
}
|
||||
|
||||
if (address_is_in_pool(server, address)) {
|
||||
if (address_is_in_pool(server, address))
|
||||
/* The requested address is in the pool. */
|
||||
|
||||
if (existing_lease && existing_lease->address != address)
|
||||
/* We previously assigned an address, but the client requested another one. Refuse. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
|
||||
return server_ack_request(server, req, address);
|
||||
}
|
||||
|
||||
/* Refuse otherwise. */
|
||||
return server_send_nak_or_ignore(server, init_reboot, req);
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ static void test_message_handler(void) {
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
test.option_server_id.address = htobe32(INADDR_LOOPBACK);
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
|
||||
@ -200,7 +200,7 @@ static void test_message_handler(void) {
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
|
||||
test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == 0);
|
||||
assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test), NULL) == DHCP_ACK);
|
||||
|
||||
/* request address reserved for static lease (unmatching client ID) */
|
||||
test.option_client_id.id[6] = 'H';
|
||||
|
Loading…
Reference in New Issue
Block a user