vp = fr_pair_list_next(vps, vp)) {
if (arg_cnt == 255) break;
- if ((vp->da != da) || (vp->vp_length > 0xff)) continue;
+ if (vp->da->flags.internal) continue;
+
+ /*
+ * Argument-List = "foo=bar"
+ */
+ if (vp->da == da) {
+ if (vp->vp_length > 0xff) continue;
+ arg_cnt++;
+ continue;
+ }
+
+ /*
+ * Maybe it's still a TACACS+ attribute?
+ */
+ if (fr_dict_by_da(vp->da) != dict_tacacs) continue;
+
+ if (!((vp->da->attr >= 1000) && (vp->da->attr <= 65000))) continue;
arg_cnt++;
}
for (vp = fr_pair_list_head(vps);
vp;
vp = fr_pair_list_next(vps,vp)) {
+ int len;
+
if (arg_cnt == 255) break;
if (arg_cnt > *arg_cnt_p) break;
- if (vp->da != da || vp->vp_length > 0xff) continue;
+ if (vp->da->flags.internal) continue;
- /* Append the <arg_N> field */
- FR_DBUFF_IN_MEMCPY_RETURN(&work_dbuff, vp->vp_strvalue, vp->vp_length);
+ /*
+ * Argument-List = "foo=bar"
+ */
+ if (vp->da == da) {
+ if (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");
+ FR_PROTO_TRACE("arg[%d] = %s", arg_cnt, vp->vp_strvalue);
+ len = vp->vp_length;
- arg_cnt_p[1 + arg_cnt] = vp->vp_length;
+ } else if (fr_dict_by_da(vp->da) != dict_tacacs) {
+ continue;
+
+ } else if (!((vp->da->attr >= 1000) && (vp->da->attr <= 65000))) {
+ continue;
+
+ } else {
+ ssize_t slen;
+ fr_sbuff_t sbuff;
+ fr_dbuff_t arg_dbuff = FR_DBUFF_MAX(&work_dbuff, 255);
+ char buffer[256];
+
+ /*
+ * Print it as "name=value"
+ */
+ FR_DBUFF_IN_MEMCPY_RETURN(&arg_dbuff, vp->da->name, strlen(vp->da->name));
+ FR_DBUFF_IN_BYTES_RETURN(&arg_dbuff, (uint8_t) '=');
+
+ sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
+ slen = fr_pair_print_value_quoted(&sbuff, vp, 0);
+ if (slen <= 0) return -1;
+
+ FR_DBUFF_IN_MEMCPY_RETURN(&arg_dbuff, buffer, slen);
+
+ FR_PROTO_TRACE("arg[%d] = %s", arg_cnt, buffer);
+
+ len = fr_dbuff_used(&arg_dbuff);
+ fr_dbuff_set(&work_dbuff, &arg_dbuff);
+ }
+
+ arg_cnt_p[1 + arg_cnt] = len;
arg_cnt++;
}
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
*/
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
*/
--- /dev/null
+# Test vectors for TACACS attributes
+#
+# Copyright 2017 Network RADIUS SARL (legal@networkradius.com)
+#
+proto tacacs
+proto-dictionary tacacs
+
+#
+# These are the same test packets as for base.txt. Instead of using the crappy format of
+#
+# Argument-List = "name=value"
+#
+# we define a test dictionary, which has defined some attributes with data types.
+#
+load-dictionary dictionary.test
+
+
+#
+# Authorization - Request: (Client -> Server)
+#
+decode-proto c0 02 01 00 e1 66 78 e6 00 00 00 35 4b c5 ea 62 13 cc ca a6 6a 03 3c 8e 3f c0 5a aa 46 da 12 cd ee 48 62 69 67 9a b8 b4 db 70 98 30 b7 fc f6 93 09 d4 3f 2c a9 58 9e 3c 6a 0e d5 50 20 e6 a5 39 46
+match Packet.Version-Major = Plus, Packet.Version-Minor = 0, Packet.Packet-Type = Authorization, Packet.Sequence-Number = 1, Packet.Flags = None, Packet.Session-Id = 3781589222, Packet.Length = 53, Packet-Body-Type = Request, Authentication-Method = TACACSPLUS, Privilege-Level = Minimum, Authentication-Type = PAP, Authentication-Service = PPP, User-Name = "bob", Client-Port = "tapioca/0", Remote-Address = "localhost", Argument-List = "service=ppp", Argument-List = "protocol=ip"
+
+encode-proto -
+match c0 02 01 00 e1 66 78 e6 00 00 00 35 4b c5 ea 62 13 cc ca a6 6a 03 3c 8e 3f c0 5a aa 46 da 12 cd ee 48 62 69 67 9a b8 b4 db 70 98 30 b7 fc f6 93 09 d4 3f 2c a9 58 9e 3c 6a 0e d5 50 20 e6 a5 39 46
+
+#
+# Authorization - Response: (Client <- Server)
+#
+decode-proto 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 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, 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
+
+#
+# Accounting - Request: (Client -> Server)
+#
+decode-proto c0 03 01 00 07 9b 35 d9 00 00 00 5b 7c 8a 99 d6 88 f9 32 3c ec 34 6d 23 89 71 72 dd 89 46 75 df 9c 00 a5 96 28 05 fc 57 88 02 0c 11 a3 60 9a 05 8b 71 6d 27 ca 83 b0 ab 2f 00 27 c8 da 58 d3 1a f1 3f 07 17 8d f6 35 c5 7b e2 07 be 29 86 d4 93 16 99 04 01 ef 03 6c 1c 2b ad 3a fb 5b 11 06 61 dc d9 09 1d 6a 08 1e
+match Packet.Version-Major = Plus, Packet.Version-Minor = 0, Packet.Packet-Type = Accounting, Packet.Sequence-Number = 1, Packet.Flags = None, Packet.Session-Id = 127612377, Packet.Length = 91, Packet-Body-Type = Request, Accounting-Flags = Start, Authentication-Method = TACACSPLUS, Privilege-Level = Minimum, Authentication-Type = PAP, Authentication-Service = PPP, User-Name = "bob", Client-Port = "tapioca/0", Remote-Address = "localhost", Argument-List = "start_time=1596565644", Argument-List = "task_id=17558", Argument-List = "service=ppp", Argument-List = "protocol=ip"
+
+encode-proto -
+match c0 03 01 00 07 9b 35 d9 00 00 00 5a 7c 8a 99 d6 88 f9 32 3c ed 21 75 25 89 18 7f d0 9f 53 64 c6 9a 0c a7 d8 37 59 ff 5b 8a 0f 08 16 bf 67 9d 02 9e 62 6b 0c e1 9e b4 a3 77 0c 23 c4 d5 5b d0 19 f2 3d 07 57 98 e4 2d f1 4d ef 5e b2 2f 84 d4 9e 5d 8f 13 05 f0 09 6a 44 66 ad 3a fb 59 0c 1d 7a d0 d5 0a 4c 3e 11
+
+count
+match 26