]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
rearrange code in preparation for encoding other attributes
authorAlan T. DeKok <aland@freeradius.org>
Tue, 7 Sep 2021 12:51:10 +0000 (08:51 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 7 Sep 2021 15:26:36 +0000 (11:26 -0400)
and also fix some bugs with encoding, where the argument count
was tracked incorrectly

src/protocols/tacacs/encode.c
src/tests/unit/protocols/tacacs/base.txt

index 6e8095c19ab4a84cee5cadc44a9879fe07826953..82571218bc739376e0a0ad575570e819fdcb0ce5 100644 (file)
 /**
  *     Encode a TACACS+ 'arg_N' fields.
  */
-static uint8_t tacacs_encode_body_arg_n_len(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_dict_attr_t const *da)
+static uint8_t tacacs_encode_body_arg_cnt(fr_pair_list_t *vps, fr_dict_attr_t const *da)
 {
        uint8_t     arg_cnt = 0;
        fr_pair_t   *vp;
-       fr_dbuff_t  work_dbuff = FR_DBUFF(dbuff);
 
        for (vp = fr_pair_list_head(vps);
             vp;
@@ -53,18 +52,13 @@ static uint8_t tacacs_encode_body_arg_n_len(fr_dbuff_t *dbuff, fr_pair_list_t *v
 
                if ((vp->da != da) || (vp->vp_length > 0xff)) continue;
 
-               /* Append the <arg_N_len> fields length */
-               fr_dbuff_in(&work_dbuff, (uint8_t) vp->vp_length);
-
                arg_cnt++;
        }
 
-       fr_dbuff_set(dbuff, &work_dbuff);
-
        return arg_cnt;
 }
 
-static ssize_t tacacs_encode_body_arg_n(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_dict_attr_t const *da)
+static ssize_t tacacs_encode_body_arg_n(fr_dbuff_t *dbuff, uint8_t *arg_cnt_p, fr_pair_list_t *vps, fr_dict_attr_t const *da)
 {
        fr_pair_t   *vp;
        uint8_t     arg_cnt = 0;
@@ -72,13 +66,19 @@ static ssize_t tacacs_encode_body_arg_n(fr_dbuff_t *dbuff, fr_pair_list_t *vps,
 
        for (vp = fr_pair_list_head(vps);
             vp;
-            vp = fr_pair_list_next(vps,vp), arg_cnt++) {
+            vp = fr_pair_list_next(vps,vp)) {
                if (arg_cnt == 255) break;
+               if (arg_cnt > *arg_cnt_p) break;
 
                if (vp->da != da || vp->vp_length > 0xff) continue;
 
                /* Append the <arg_N> field */
                FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, vp->vp_strvalue, vp->vp_length);
+
+               FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), "argument");
+
+               arg_cnt_p[1 + arg_cnt] = vp->vp_length;
+               arg_cnt++;
        }
 
        return fr_dbuff_set(dbuff, &work_dbuff);
@@ -101,6 +101,8 @@ static ssize_t tacacs_encode_field(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_di
                FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, vp->vp_octets, vp->vp_length);
        }
 
+       FR_PROTO_HEX_DUMP(fr_dbuff_start(&work_dbuff), fr_dbuff_used(&work_dbuff), da->name);
+
        return fr_dbuff_set(dbuff, &work_dbuff);
 }
 
@@ -402,7 +404,8 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                        /*
                         *      Encode 'arg_N' arguments (horrible format)
                         */
-                       packet->author.req.arg_cnt = tacacs_encode_body_arg_n_len(&work_dbuff, vps, attr_tacacs_argument_list);
+                       packet->author.req.arg_cnt = tacacs_encode_body_arg_cnt(vps, attr_tacacs_argument_list);
+                       if (packet->author.req.arg_cnt) FR_DBUFF_MEMSET_RETURN(&work_dbuff, 0, packet->author.req.arg_cnt);
 
                        /*
                         *      Encode 3 mandatory fields.
@@ -411,11 +414,13 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                        ENCODE_FIELD_STRING8(packet->author.req.port_len, attr_tacacs_client_port);
                        ENCODE_FIELD_STRING8(packet->author.req.rem_addr_len, attr_tacacs_remote_address);
 
+                       fprintf(stderr, "ARG CNT %d at %d\n", packet->author.req.arg_cnt, __LINE__);
+
                        /*
                         *      Append 'args_body' to the end of buffer
                         */
                        if (packet->author.req.arg_cnt > 0) {
-                               if (tacacs_encode_body_arg_n(&work_dbuff, vps, attr_tacacs_argument_list) < 0) goto error;
+                               if (tacacs_encode_body_arg_n(&work_dbuff, &packet->author.req.arg_cnt, vps, attr_tacacs_argument_list) < 0) goto error;
                        }
 
                        goto check_request;
@@ -470,7 +475,8 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                         */
                        if (!((packet->author.res.status == FR_AUTHORIZATION_STATUS_VALUE_ERROR) ||
                              (packet->author.res.status == FR_AUTHORIZATION_STATUS_VALUE_FOLLOW))) {
-                               packet->author.res.arg_cnt = tacacs_encode_body_arg_n_len(&work_dbuff, vps, attr_tacacs_argument_list);
+                               packet->author.res.arg_cnt = tacacs_encode_body_arg_cnt(vps, attr_tacacs_argument_list);
+                               if (packet->author.res.arg_cnt) FR_DBUFF_MEMSET_RETURN(&work_dbuff, 0, packet->author.res.arg_cnt);
                        } else {
                                packet->author.res.arg_cnt = 0;
                        }
@@ -481,11 +487,13 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                        ENCODE_FIELD_STRING16(packet->author.res.server_msg_len, attr_tacacs_server_message);
                        ENCODE_FIELD_STRING16(packet->author.res.data_len, attr_tacacs_data);
 
+                       fprintf(stderr, "ARG CNT %d at %d\n", packet->author.res.arg_cnt, __LINE__);
+
                        /*
                         *      Append 'args_body' to the end of buffer
                         */
                        if (packet->author.res.arg_cnt > 0) {
-                               if (tacacs_encode_body_arg_n(&work_dbuff, vps, attr_tacacs_argument_list) < 0) goto error;
+                               if (tacacs_encode_body_arg_n(&work_dbuff, &packet->author.res.arg_cnt, vps, attr_tacacs_argument_list) < 0) goto error;
                        }
 
                        goto check_reply;
@@ -541,7 +549,8 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                        /*
                         *      Encode 'arg_N' arguments (horrible format)
                         */
-                       packet->acct.req.arg_cnt = tacacs_encode_body_arg_n_len(&work_dbuff, vps, attr_tacacs_argument_list);
+                       packet->acct.req.arg_cnt = tacacs_encode_body_arg_cnt(vps, attr_tacacs_argument_list);
+                       if (packet->acct.req.arg_cnt) FR_DBUFF_MEMSET_RETURN(&work_dbuff, 0, packet->acct.req.arg_cnt);
 
                        /*
                         *      Encode 3 mandatory fields.
@@ -550,11 +559,13 @@ ssize_t fr_tacacs_encode(fr_dbuff_t *dbuff, uint8_t const *original_packet, char
                        ENCODE_FIELD_STRING8(packet->acct.req.port_len, attr_tacacs_client_port);
                        ENCODE_FIELD_STRING8(packet->acct.req.rem_addr_len, attr_tacacs_remote_address);
 
+                       fprintf(stderr, "ARG CNT %d at %d\n", packet->acct.req.arg_cnt, __LINE__);
+
                        /*
                         *      Append 'args_body' to the end of buffer
                         */
                        if (packet->acct.req.arg_cnt > 0) {
-                               if (tacacs_encode_body_arg_n(&work_dbuff, vps, attr_tacacs_argument_list) < 0) goto error;
+                               if (tacacs_encode_body_arg_n(&work_dbuff, &packet->acct.req.arg_cnt, vps, attr_tacacs_argument_list) < 0) goto error;
                        }
 
                check_request:
index e2898046f5c2c3c4172fa3735b821d113d92c538..56561c975ba91ce0504400486b7b53cf1209374e 100644 (file)
@@ -46,7 +46,7 @@ decode-proto c0 02 02 00 e1 66 78 e6 00 00 00 13 02 59 f9 90 38 81 e1 bb 9d a6 1
 match Packet.Version-Major = Plus, Packet.Version-Minor = 0, Packet.Packet-Type = Authorization, Packet.Sequence-Number = 2, Packet.Flags = None, Packet.Session-Id = 3781589222, Packet.Length = 19, Packet-Body-Type = Response, Authorization-Status = Pass-Add, Server-Message = "", Data = 0x, Argument-List = "addr=1.2.3.4"
 
 encode-proto -
-match c0 02 02 00 e1 66 78 e6 00 00 00 13 02 59 f9 90 38 81 e1 bb 9d a6 13 93 fc 86 7e 4a 14 1c 24
+match c0 02 02 00 e1 66 78 e6 00 00 00 13 02 59 f5 90 38 81 ed bb 9d a6 13 93 fc 86 7e 4a 14 1c 24
 
 #
 #  Accounting - Request: (Client -> Server)