From: Alan T. DeKok Date: Tue, 15 Mar 2022 21:24:17 +0000 (-0400) Subject: encode bools properly X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abd736764099124eae8e29caafbec4572962d515;p=thirdparty%2Ffreeradius-server.git encode bools properly adding fr_dhcpv4_next_encodable, and updating encode_value() the decoder was already correct. --- diff --git a/share/dictionary/dhcpv4/dictionary.rfc2131 b/share/dictionary/dhcpv4/dictionary.rfc2131 index 0570f939078..2a9f5f9e372 100644 --- a/share/dictionary/dhcpv4/dictionary.rfc2131 +++ b/share/dictionary/dhcpv4/dictionary.rfc2131 @@ -48,8 +48,8 @@ ATTRIBUTE Swap-Server 16 ipaddr # Path name for root disk ATTRIBUTE Root-Path 17 string ATTRIBUTE Bootp-Extensions-Path 18 string -ATTRIBUTE IP-Forward-Enable 19 byte -ATTRIBUTE Source-Route-Enable 20 byte +ATTRIBUTE IP-Forward-Enable 19 bool +ATTRIBUTE Source-Route-Enable 20 bool # Routing Policy Filters ATTRIBUTE Policy-Filter 21 octets ATTRIBUTE Max-Datagram-Reassembly-Size 22 short @@ -57,20 +57,20 @@ ATTRIBUTE Default-IP-TTL 23 octets ATTRIBUTE Path-MTU-Aging-Timeout 24 integer ATTRIBUTE Path-MTU-Plateau-Table 25 short array ATTRIBUTE Interface-MTU-Size 26 short -ATTRIBUTE All-Subnets-Are-Local 27 byte +ATTRIBUTE All-Subnets-Are-Local 27 bool ATTRIBUTE Broadcast-Address 28 ipaddr -ATTRIBUTE Perform-Mask-Discovery 29 byte -ATTRIBUTE Provide-Mask-To-Others 30 byte -ATTRIBUTE Perform-Router-Discovery 31 byte +ATTRIBUTE Perform-Mask-Discovery 29 bool +ATTRIBUTE Provide-Mask-To-Others 30 bool +ATTRIBUTE Perform-Router-Discovery 31 bool ATTRIBUTE Router-Solicitation-Address 32 ipaddr # first is destination address, second is router. ATTRIBUTE Static-Routes 33 ipaddr array -ATTRIBUTE Trailer-Encapsulation 34 byte +ATTRIBUTE Trailer-Encapsulation 34 bool ATTRIBUTE ARP-Cache-Timeout 35 integer -ATTRIBUTE Ethernet-Encapsulation 36 byte +ATTRIBUTE Ethernet-Encapsulation 36 bool ATTRIBUTE Default-TCP-TTL 37 byte ATTRIBUTE Keep-Alive-Interval 38 integer -ATTRIBUTE Keep-Alive-Garbage 39 byte +ATTRIBUTE Keep-Alive-Garbage 39 bool ATTRIBUTE NIS-Domain-Name 40 string ATTRIBUTE NIS-Servers 41 ipaddr array ATTRIBUTE NTP-Servers 42 ipaddr array @@ -144,7 +144,7 @@ ATTRIBUTE Directory-Agent 78 octets # service location agent scope ATTRIBUTE Service-Scope 79 octets # Rapid Commit -ATTRIBUTE Rapid-Commit 80 octets +ATTRIBUTE Rapid-Commit 80 bool # 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 e9f0ac703d2..00a0a9b2096 100644 --- a/src/protocols/dhcpv4/base.c +++ b/src/protocols/dhcpv4/base.c @@ -288,6 +288,27 @@ bool fr_dhcpv4_is_encodable(void const *item, UNUSED void const *uctx) return (vp->da->dict == dict_dhcpv4) && (!vp->da->flags.internal); } +/** DHCPV4-specific iterator + * + */ +void *fr_dhcpv4_next_encodable(fr_dlist_head_t *list, void *to_eval, void *uctx) +{ + fr_pair_t *c; + fr_dict_t *dict = talloc_get_type_abort(uctx, fr_dict_t); + + if (!to_eval) return NULL; + + 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; + + break; + } + + return c; +} + ssize_t fr_dhcpv4_encode(uint8_t *buffer, size_t buflen, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps) { return fr_dhcpv4_encode_dbuff(&FR_DBUFF_TMP(buffer, buflen), original, code, xid, vps); @@ -481,7 +502,7 @@ ssize_t fr_dhcpv4_encode_dbuff(fr_dbuff_t *dbuff, dhcp_packet_t *original, int c * operates correctly. This changes the order of the list, but never mind... */ fr_pair_list_sort(vps, fr_dhcpv4_attr_cmp); - fr_pair_dcursor_iter_init(&cursor, vps, fr_proto_next_encodable, dict_dhcpv4); + fr_pair_dcursor_iter_init(&cursor, vps, fr_dhcpv4_next_encodable, dict_dhcpv4); /* * Each call to fr_dhcpv4_encode_option will encode one complete DHCP option, diff --git a/src/protocols/dhcpv4/dhcpv4.h b/src/protocols/dhcpv4/dhcpv4.h index 5fd41c28bd2..7bf7cdd5d69 100644 --- a/src/protocols/dhcpv4/dhcpv4.h +++ b/src/protocols/dhcpv4/dhcpv4.h @@ -154,6 +154,7 @@ int8_t fr_dhcpv4_attr_cmp(void const *a, void const *b); bool fr_dhcpv4_ok(uint8_t const *data, ssize_t data_len, uint8_t *message_type, uint32_t *xid); fr_radius_packet_t *fr_dhcpv4_packet_alloc(uint8_t const *data, ssize_t data_len); bool fr_dhcpv4_is_encodable(void const *item, void const *uctx); +void *fr_dhcpv4_next_encodable(fr_dlist_head_t *list, void *to_eval, void *uctx); ssize_t fr_dhcpv4_encode(uint8_t *buffer, size_t buflen, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps); ssize_t fr_dhcpv4_encode_dbuff(fr_dbuff_t *dbuff, dhcp_packet_t *original, int code, uint32_t xid, fr_pair_list_t *vps); int fr_dhcpv4_global_init(void); diff --git a/src/protocols/dhcpv4/encode.c b/src/protocols/dhcpv4/encode.c index e370432358e..4baeb89e5e7 100644 --- a/src/protocols/dhcpv4/encode.c +++ b/src/protocols/dhcpv4/encode.c @@ -73,7 +73,7 @@ static ssize_t encode_value_trampoline(fr_dbuff_t *dbuff, * @param[in,out] cursor Current attribute we're encoding. * @param[in] encode_ctx Containing DHCPv4 dictionary. * @return - * - The length of data written. + * - The length of data written, may return 0 for bools * < 0 if there's not enough space or option type is unsupported */ static ssize_t encode_value(fr_dbuff_t *dbuff, @@ -114,6 +114,15 @@ static ssize_t encode_value(fr_dbuff_t *dbuff, FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, (uint8_t const *)&vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr)); break; + /* + * "option exists" == true. + * "option does not exist" == false + * + * fr_dhcpv4_next_encodable() takes care of skipping bools which are false. + */ + case FR_TYPE_BOOL: + break; + default: slen = fr_value_box_to_network(&work_dbuff, &vp->data); if (slen < 0) return slen; @@ -824,7 +833,8 @@ static int encode_test_ctx(void **out, TALLOC_CTX *ctx) extern fr_test_point_pair_encode_t dhcpv4_tp_encode_pair; fr_test_point_pair_encode_t dhcpv4_tp_encode_pair = { .test_ctx = encode_test_ctx, - .func = fr_dhcpv4_encode_option + .func = fr_dhcpv4_encode_option, + .next_encodable = fr_dhcpv4_next_encodable, }; diff --git a/src/tests/unit/protocols/dhcpv4/base.txt b/src/tests/unit/protocols/dhcpv4/base.txt index 51ebb560c48..a093d642425 100644 --- a/src/tests/unit/protocols/dhcpv4/base.txt +++ b/src/tests/unit/protocols/dhcpv4/base.txt @@ -5,6 +5,18 @@ 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 # @@ -51,15 +63,15 @@ match Message-Type = Discover, Client-Identifier = 0x01001ceaadac1e, Parameter-R encode-pair Relay-Agent-Information.Circuit-Id = 'oh hai this is an agent, how are you doing DHCP server? this is a really long agent circuit id, which will occupy most of the maximum size for an option so that the next sub option will not fit and a new option will be needed', Relay-Agent-Information.Remote-Id = 'trying to add a sub option agent remote id' match 52 e3 01 e1 6f 68 20 68 61 69 20 74 68 69 73 20 69 73 20 61 6e 20 61 67 65 6e 74 2c 20 68 6f 77 20 61 72 65 20 79 6f 75 20 64 6f 69 6e 67 20 44 48 43 50 20 73 65 72 76 65 72 3f 20 74 68 69 73 20 69 73 20 61 20 72 65 61 6c 6c 79 20 6c 6f 6e 67 20 61 67 65 6e 74 20 63 69 72 63 75 69 74 20 69 64 2c 20 77 68 69 63 68 20 77 69 6c 6c 20 6f 63 63 75 70 79 20 6d 6f 73 74 20 6f 66 20 74 68 65 20 6d 61 78 69 6d 75 6d 20 73 69 7a 65 20 66 6f 72 20 61 6e 20 6f 70 74 69 6f 6e 20 73 6f 20 74 68 61 74 20 74 68 65 20 6e 65 78 74 20 73 75 62 20 6f 70 74 69 6f 6e 20 77 69 6c 6c 20 6e 6f 74 20 66 69 74 20 61 6e 64 20 61 20 6e 65 77 20 6f 70 74 69 6f 6e 20 77 69 6c 6c 20 62 65 20 6e 65 65 64 65 64 52 2c 02 2a 74 72 79 69 6e 67 20 74 6f 20 61 64 64 20 61 20 73 75 62 20 6f 70 74 69 6f 6e 20 61 67 65 6e 74 20 72 65 6d 6f 74 65 20 69 64 -# An empty option (Rapid Commit) -encode-pair Rapid-Commit = '' -match 50 00 +# An empty octets option +encode-pair Merit-Dump-File = '' +match 0e 00 # # Decoding empty options yields empty data # decode-pair - -match Rapid-Commit = 0x +match Merit-Dump-File = 0x # 255 bytes are OK encode-pair Domain-Name = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @@ -105,4 +117,4 @@ decode-pair - match Relay-Agent-Information.Circuit-Id = 0x3132333435363738396131323334353637383962313233343536373839633132333435363738396431323334353637383965313233343536373839663132333435363738396731323334353637383968313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396131323334353637383961313233343536373839613132333435363738396178797a count -match 45 +match 51