From: Alan T. DeKok Date: Thu, 17 Mar 2022 15:30:55 +0000 (-0400) Subject: allow for Rapid-Commit to be special X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=31fa68c3ac2d3c1e394b711276a6fd427066ee7c;p=thirdparty%2Ffreeradius-server.git allow for Rapid-Commit to be special normal bools are encoded as 1 byte of 0/1 Rapid-Commit is stupid, and gets stupid encoding. --- diff --git a/share/dictionary/dhcpv4/dictionary.rfc2131 b/share/dictionary/dhcpv4/dictionary.rfc2131 index f2d418782e8..450bdfd1991 100644 --- a/share/dictionary/dhcpv4/dictionary.rfc2131 +++ b/share/dictionary/dhcpv4/dictionary.rfc2131 @@ -141,7 +141,7 @@ ATTRIBUTE STDA-Server-Address 76 ipaddr array ATTRIBUTE User-Class 77 octets # Rapid Commit -ATTRIBUTE Rapid-Commit 80 bool +ATTRIBUTE Rapid-Commit 80 bool encode=exists # Fully Qualified Domain Name ATTRIBUTE Client-FQDN 81 string # Relay Agent Information diff --git a/src/protocols/dhcpv4/base.c b/src/protocols/dhcpv4/base.c index e9c9437e437..ae5e52c3dd0 100644 --- a/src/protocols/dhcpv4/base.c +++ b/src/protocols/dhcpv4/base.c @@ -371,7 +371,8 @@ void *fr_dhcpv4_next_encodable(fr_dlist_head_t *list, void *to_eval, void *uctx) for (c = to_eval; c; c = fr_dlist_next(list, c)) { PAIR_VERIFY(c); if (c->da->dict != dict || c->da->flags.internal) continue; - if (c->da->type == FR_TYPE_BOOL && !c->vp_bool) continue; + + if (c->da->type == FR_TYPE_BOOL && da_is_bool_exists(c->da) && !c->vp_bool) continue; break; } @@ -746,6 +747,7 @@ static fr_table_num_ordered_t const subtype_table[] = { { L("dns_label"), FLAG_ENCODE_DNS_LABEL }, { L("encode=dns_label"), FLAG_ENCODE_DNS_LABEL }, { L("prefix=split"), FLAG_ENCODE_SPLIT_PREFIX }, + { L("encode=exists"), FLAG_ENCODE_BOOL_EXISTS }, }; static bool attr_valid(UNUSED fr_dict_t *dict, UNUSED fr_dict_attr_t const *parent, @@ -783,6 +785,11 @@ static bool attr_valid(UNUSED fr_dict_t *dict, UNUSED fr_dict_attr_t const *pare return false; } + if ((type != FR_TYPE_BOOL) && (flags->subtype == FLAG_ENCODE_BOOL_EXISTS)) { + fr_strerror_const("The 'encode=exists' flag can only be used with attributes of type 'bool'"); + return false; + } + return true; } diff --git a/src/protocols/dhcpv4/dhcpv4.h b/src/protocols/dhcpv4/dhcpv4.h index bf8445fa42c..31262f466f3 100644 --- a/src/protocols/dhcpv4/dhcpv4.h +++ b/src/protocols/dhcpv4/dhcpv4.h @@ -72,10 +72,12 @@ enum { FLAG_ENCODE_NONE = 0, //!< no particular encoding for DHCPv6 strings FLAG_ENCODE_DNS_LABEL, //!< encode as DNS label FLAG_ENCODE_SPLIT_PREFIX, //!< encode IPv4 prefixes as Policy-Filter, split into IP/mask + FLAG_ENCODE_BOOL_EXISTS, //!< bool as existence checks }; #define da_is_dns_label(_da) (!(_da)->flags.extra && ((_da)->flags.subtype == FLAG_ENCODE_DNS_LABEL)) #define da_is_split_prefix(_da) (!(_da)->flags.extra && ((_da)->flags.subtype == FLAG_ENCODE_SPLIT_PREFIX)) +#define da_is_bool_exists(_da) (!(_da)->flags.extra && ((_da)->flags.subtype == FLAG_ENCODE_BOOL_EXISTS)) typedef struct { uint8_t opcode; diff --git a/src/protocols/dhcpv4/encode.c b/src/protocols/dhcpv4/encode.c index 45bb7bb541f..58758e5a035 100644 --- a/src/protocols/dhcpv4/encode.c +++ b/src/protocols/dhcpv4/encode.c @@ -125,6 +125,10 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, * Rapid-Commit does this. Options 19/20 require encoding as one byte of 0/1. */ case FR_TYPE_BOOL: + if (da_is_bool_exists(vp->da)) { + break; + } + fr_dbuff_in(&work_dbuff, (uint8_t) (vp->vp_bool == true)); break; case FR_TYPE_IPV4_PREFIX: diff --git a/src/tests/unit/protocols/dhcpv4/base.txt b/src/tests/unit/protocols/dhcpv4/base.txt index a093d642425..eedfaee231c 100644 --- a/src/tests/unit/protocols/dhcpv4/base.txt +++ b/src/tests/unit/protocols/dhcpv4/base.txt @@ -5,18 +5,6 @@ proto dhcpv4 proto-dictionary dhcpv4 fuzzer-out dhcpv4 -# -# bools which are false don't get encoded -# -encode-pair IP-Forward-Enable = false -match - -encode-pair IP-Forward-Enable = true -match 13 00 - -decode-pair - -match IP-Forward-Enable = yes - # # DHCP TLV types # @@ -117,4 +105,4 @@ decode-pair - match Relay-Agent-Information.Circuit-Id = 0x3132333435363738396131323334353637383962313233343536373839633132333435363738396431323334353637383965313233343536373839663132333435363738396731323334353637383968313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396178797a count -match 51 +match 45 diff --git a/src/tests/unit/protocols/dhcpv4/bools.txt b/src/tests/unit/protocols/dhcpv4/bools.txt new file mode 100644 index 00000000000..b317099c4a2 --- /dev/null +++ b/src/tests/unit/protocols/dhcpv4/bools.txt @@ -0,0 +1,64 @@ +# +# Test vectors for bools, which are shit and random. +# +proto dhcpv4 +proto-dictionary dhcpv4 +fuzzer-out dhcpv4 + +encode-pair Rapid-Commit = yes +match 50 00 + +decode-pair - +match Rapid-Commit = yes + +# +# false is "don't encode" +# +encode-pair Rapid-Commit = false +match + +# +# Normal bools get encoded as 0/1 +# +encode-pair IP-Forward-Enable = false +match 13 01 00 + +encode-pair IP-Forward-Enable = true +match 13 01 01 + +decode-pair - +match IP-Forward-Enable = yes + +# +# All non-zero values are "true" +# +decode-pair 13 01 88 +match IP-Forward-Enable = yes + +# +# Rapid-Commit is stupid +# +encode-pair Rapid-Commit = yes +match 50 00 + +decode-pair - +match Rapid-Commit = yes + +# +# false is "don't encode" +# +encode-pair Rapid-Commit = false +match + +# +# We allow Rapid-Commit to be normal, if it so chooses +# +decode-pair 50 01 00 +match Rapid-Commit = no + +decode-pair 50 01 01 +match Rapid-Commit = yes + + +count +match 27