mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
networkd: Add support for blacklisting servers
closes #6260 fuzzer: Add DHCP support for blacklisting servers
This commit is contained in:
parent
53ab531954
commit
727b573418
@ -1566,6 +1566,13 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>BlackList=</varname></term>
|
||||
<listitem>
|
||||
<para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -532,7 +532,7 @@ int sd_dhcp_client_set_max_attempts(sd_dhcp_client *client, uint64_t max_attempt
|
||||
int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
||||
assert_return(client, -EINVAL);
|
||||
|
||||
if (!IN_SET(client->state, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
|
||||
if (!IN_SET(client->state, DHCP_STATE_SELECTING, DHCP_STATE_BOUND, DHCP_STATE_RENEWING, DHCP_STATE_REBINDING))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
if (ret)
|
||||
@ -541,11 +541,13 @@ int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void client_notify(sd_dhcp_client *client, int event) {
|
||||
static int client_notify(sd_dhcp_client *client, int event) {
|
||||
assert(client);
|
||||
|
||||
if (client->callback)
|
||||
client->callback(client, event, client->userdata);
|
||||
return client->callback(client, event, client->userdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_initialize(sd_dhcp_client *client) {
|
||||
@ -1328,6 +1330,9 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_
|
||||
sd_dhcp_lease_unref(client->lease);
|
||||
client->lease = TAKE_PTR(lease);
|
||||
|
||||
if (client_notify(client, SD_DHCP_CLIENT_EVENT_SELECTING) < 0)
|
||||
return -ENOMSG;
|
||||
|
||||
log_dhcp_client(client, "OFFER");
|
||||
|
||||
return 0;
|
||||
|
@ -418,7 +418,7 @@ static uint8_t test_addr_acq_ack[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
static int test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
void *userdata) {
|
||||
sd_event *e = userdata;
|
||||
sd_dhcp_lease *lease;
|
||||
@ -426,7 +426,7 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
const struct in_addr *addrs;
|
||||
|
||||
assert_se(client);
|
||||
assert_se(event == SD_DHCP_CLIENT_EVENT_IP_ACQUIRE);
|
||||
assert_se(IN_SET(event, SD_DHCP_CLIENT_EVENT_IP_ACQUIRE, SD_DHCP_CLIENT_EVENT_SELECTING));
|
||||
|
||||
assert_se(sd_dhcp_client_get_lease(client, &lease) >= 0);
|
||||
assert_se(lease);
|
||||
@ -447,6 +447,8 @@ static void test_addr_acq_acquired(sd_dhcp_client *client, int event,
|
||||
printf(" DHCP address acquired\n");
|
||||
|
||||
sd_event_exit(e, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_addr_acq_recv_request(size_t size, DHCPMessage *request) {
|
||||
|
@ -512,7 +512,35 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
static int dhcp_server_is_black_listed(Link *link, sd_dhcp_client *client) {
|
||||
sd_dhcp_lease *lease;
|
||||
struct in_addr addr;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(client);
|
||||
|
||||
r = sd_dhcp_client_get_lease(client, &lease);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
|
||||
|
||||
r = sd_dhcp_lease_get_server_identifier(lease, &addr);
|
||||
if (r < 0)
|
||||
return log_link_debug_errno(link, r, "Failed to get DHCP server ip address: %m");
|
||||
|
||||
if (set_contains(link->network->dhcp_black_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
|
||||
log_struct(LOG_DEBUG,
|
||||
LOG_LINK_INTERFACE(link),
|
||||
LOG_LINK_MESSAGE(link, "DHCPv4 ip '%u.%u.%u.%u' found in black listed ip addresses, ignoring offer",
|
||||
ADDRESS_FMT_VAL(addr)));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
Link *link = userdata;
|
||||
int r = 0;
|
||||
|
||||
@ -521,7 +549,7 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
assert(link->manager);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
switch (event) {
|
||||
case SD_DHCP_CLIENT_EVENT_STOP:
|
||||
@ -532,10 +560,8 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
log_link_debug(link, "DHCP client is stopped. Acquiring IPv4 link-local address");
|
||||
|
||||
r = sd_ipv4ll_start(link->ipv4ll);
|
||||
if (r < 0) {
|
||||
log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
|
||||
return;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
|
||||
}
|
||||
|
||||
_fallthrough_;
|
||||
@ -544,14 +570,14 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
|
||||
if (link->network->dhcp_critical) {
|
||||
log_link_error(link, "DHCPv4 connection considered system critical, ignoring request to reconfigure it.");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (link->dhcp_lease) {
|
||||
r = dhcp_lease_lost(link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@ -559,7 +585,7 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
r = dhcp_lease_acquired(client, link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,16 +594,23 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
r = dhcp_lease_renew(client, link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
|
||||
r = dhcp_lease_acquired(client, link);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return;
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case SD_DHCP_CLIENT_EVENT_SELECTING:
|
||||
r = dhcp_server_is_black_listed(link, client);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r != 0)
|
||||
return -ENOMSG;
|
||||
break;
|
||||
default:
|
||||
if (event < 0)
|
||||
log_link_warning_errno(link, event, "DHCP error: Client failed: %m");
|
||||
@ -586,7 +619,7 @@ static void dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_set_hostname(Link *link) {
|
||||
|
@ -150,6 +150,7 @@ DHCP.UseTimezone, config_parse_bool,
|
||||
DHCP.IAID, config_parse_iaid, 0, 0
|
||||
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
|
||||
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, rapid_commit)
|
||||
DHCP.BlackList, config_parse_dhcp_black_listed_ip_address, 0, 0
|
||||
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
|
||||
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
|
||||
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
|
||||
|
@ -512,7 +512,7 @@ static Network *network_free(Network *network) {
|
||||
free(network->dhcp_vendor_class_identifier);
|
||||
strv_free(network->dhcp_user_class);
|
||||
free(network->dhcp_hostname);
|
||||
|
||||
set_free(network->dhcp_black_listed_ip);
|
||||
free(network->mac);
|
||||
|
||||
strv_free(network->ntp);
|
||||
@ -1620,6 +1620,71 @@ int config_parse_dhcp_max_attempts(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_dhcp_black_listed_ip_address(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = data;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
network->dhcp_black_listed_ip = set_free(network->dhcp_black_listed_ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = rvalue;;) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
union in_addr_union ip;
|
||||
|
||||
r = extract_first_word(&p, &n, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse DHCP black listed ip address, ignoring assignment: %s",
|
||||
rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = in_addr_from_string(AF_INET, n, &ip);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"DHCP black listed ip address is invalid, ignoring assignment: %s", n);
|
||||
continue;
|
||||
}
|
||||
|
||||
r = set_ensure_allocated(&network->dhcp_black_listed_ip, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = set_put(network->dhcp_black_listed_ip, UINT32_TO_PTR(ip.in.s_addr));
|
||||
if (r == -EEXIST) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"DHCP black listed ip address is duplicated, ignoring assignment: %s", n);
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to store DHCP black listed ip address '%s', ignoring assignment: %m", n);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp_use_domains, dhcp_use_domains, DHCPUseDomains,
|
||||
"Failed to parse DHCP use domains setting");
|
||||
|
||||
|
@ -135,6 +135,7 @@ struct Network {
|
||||
bool dhcp_use_hostname;
|
||||
bool dhcp_route_table_set;
|
||||
DHCPUseDomains dhcp_use_domains;
|
||||
Set *dhcp_black_listed_ip;
|
||||
|
||||
/* DHCP Server Support */
|
||||
bool dhcp_server;
|
||||
@ -305,6 +306,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_privacy_extensions);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_hostname);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_timezone);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_black_listed_ip_address);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
|
||||
|
@ -38,6 +38,7 @@ enum {
|
||||
SD_DHCP_CLIENT_EVENT_IP_CHANGE = 2,
|
||||
SD_DHCP_CLIENT_EVENT_EXPIRED = 3,
|
||||
SD_DHCP_CLIENT_EVENT_RENEW = 4,
|
||||
SD_DHCP_CLIENT_EVENT_SELECTING = 5,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -98,7 +99,7 @@ enum {
|
||||
|
||||
typedef struct sd_dhcp_client sd_dhcp_client;
|
||||
|
||||
typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
|
||||
typedef int (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
|
||||
int sd_dhcp_client_set_callback(
|
||||
sd_dhcp_client *client,
|
||||
sd_dhcp_client_callback_t cb,
|
||||
|
@ -59,6 +59,7 @@ ClientIdentifier=
|
||||
ListenPort=
|
||||
UseTimezone=
|
||||
RouteTable=
|
||||
BlackList=
|
||||
[Route]
|
||||
Destination=
|
||||
Protocol=
|
||||
|
Loading…
Reference in New Issue
Block a user