26#include <freeradius-devel/util/net.h>
27#include <freeradius-devel/util/md5.h>
28#include <freeradius-devel/util/struct.h>
121 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_START] =
"Authentication-Start",
122 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_PASS] =
"Authentication-Pass",
123 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_FAIL] =
"Authentication-Fail",
124 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_GETDATA] =
"Authentication-GetData",
125 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_GETUSER] =
"Authentication-GetUser",
126 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_GETPASS] =
"Authentication-GetPass",
127 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_RESTART] =
"Authentication-Restart",
128 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_ERROR] =
"Authentication-Error",
130 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_CONTINUE] =
"Authentication-Continue",
131 [FR_PACKET_TYPE_VALUE_AUTHENTICATION_CONTINUE_ABORT] =
"Authentication-Continue-Abort",
133 [FR_PACKET_TYPE_VALUE_AUTHORIZATION_REQUEST] =
"Authorization-Request",
134 [FR_PACKET_TYPE_VALUE_AUTHORIZATION_PASS_ADD] =
"Authorization-Pass-Add",
135 [FR_PACKET_TYPE_VALUE_AUTHORIZATION_PASS_REPLACE] =
"Authorization-Pass-Replace",
136 [FR_PACKET_TYPE_VALUE_AUTHORIZATION_FAIL] =
"Authorization-Fail",
137 [FR_PACKET_TYPE_VALUE_AUTHORIZATION_ERROR] =
"Authorization-Error",
139 [FR_PACKET_TYPE_VALUE_ACCOUNTING_REQUEST] =
"Accounting-Request",
140 [FR_PACKET_TYPE_VALUE_ACCOUNTING_SUCCESS] =
"Accounting-Success",
141 [FR_PACKET_TYPE_VALUE_ACCOUNTING_ERROR] =
"Accounting-Error",
159 fr_strerror_const(
"Failed to encrypt/decrept the packet, as the secret has zero length.");
172 memcpy(&buf[
sizeof(pkt->
hdr.
session_id) + secret_len], &pkt->
hdr.version,
sizeof(pkt->
hdr.version));
177 end = body + body_len;
184 if (++body == end)
goto done;
220 if (buffer_len <
sizeof(pkt->
hdr)) {
221 return sizeof(pkt->
hdr);
252 if (buffer_len < length)
return length;
268 want =
sizeof(pkt->
hdr) +
sizeof(pkt->authen_start);
271 want =
sizeof(pkt->
hdr) +
sizeof(pkt->authen_cont);
275 want =
sizeof(pkt->
hdr) +
sizeof(pkt->authen_reply);
281 want =
sizeof(pkt->
hdr) +
sizeof(pkt->author_req);
284 want =
sizeof(pkt->
hdr) +
sizeof(pkt->author_reply);
290 want =
sizeof(pkt->
hdr) +
sizeof(pkt->acct_req);
293 want =
sizeof(pkt->
hdr) +
sizeof(pkt->acct_reply);
308 if (!datalen)
return;
317 if (!datalen)
return;
325 for (p =
data; p < (
data + datalen); p++) {
326 if ((*p < 0x20) || (*p > 0x80))
goto hex;
332#define CHECK(_length) do { \
333 size_t plen = _length; \
334 if ((size_t) (end - p) < plen) { \
335 fr_log_hex(log, L_DBG, file, line, p, end - p, "%s", " TRUNCATED "); \
344#define ASCII(_prefix, _field) do { \
346 print_ascii(log, file, line, _prefix, data, data_len); \
350#define HEXIT(_prefix, _field) do { \
352 print_hex(log, file, line, _prefix, data, data_len); \
355#define PRINT(_fmt, ...) fr_log(log, L_DBG, file, line, _fmt, ## __VA_ARGS__)
364 if (argv + arg_cnt > end) {
365 PRINT(
" ARG cnt overflows packet");
370 for (i = 0; i < arg_cnt; i++) {
372 PRINT(
" ARG[%zu] is at EOF", i);
376 if ((end - p) < argv[i]) {
377 PRINT(
" ARG[%zu] overflows packet", i);
382 snprintf(prefix,
sizeof(prefix),
" arg[%zu] ", i);
385 ASCII(prefix, argv[i]);
391 size_t length, data_len;
396 end = ((
uint8_t const *) packet) + packet_len;
398 if (packet_len < 12) {
406 PRINT(
" major %d", (p[0] & 0xf0) >> 4);
407 PRINT(
" minor %d", (p[0] & 0x0f));
409 PRINT(
" type %02x", p[1]);
410 PRINT(
" seq_no %02x", p[2]);
411 PRINT(
" flags %02x", p[3]);
419 if ((p[3] & 0x01) == 0) {
420 PRINT(
" ... encrypted ...");
424 if (length > 65535) {
432 if ((p + length) != end) {
433 PRINT(
"length field does not match input packet length %08lx", packet_len - 12);
437#define REQUIRE(_length) do { \
438 size_t plen = _length; \
439 if ((size_t) (end - hdr) < plen) { \
440 print_hex(log, file, line, " TRUNCATED ", hdr, end - hdr); \
453 PRINT(
" authentication-start");
457 PRINT(
" action %02x", hdr[0]);
458 PRINT(
" priv_lvl %02x", hdr[1]);
459 PRINT(
" authen_type %02x", hdr[2]);
460 PRINT(
" authen_service %02x", hdr[3]);
461 PRINT(
" user_len %02x", hdr[4]);
462 PRINT(
" port_len %02x", hdr[5]);
463 PRINT(
" rem_addr_len %02x", hdr[6]);
464 PRINT(
" data_len %02x", hdr[7]);
466 ASCII(
" user ", hdr[4]);
467 ASCII(
" port ", hdr[5]);
468 ASCII(
" rem_addr ", hdr[6]);
469 HEXIT(
" data ", hdr[7]);
472 PRINT(
" authentication-continue");
478 PRINT(
" flags %02x", hdr[4]);
486 PRINT(
" authentication-reply");
490 PRINT(
" status %02x", hdr[0]);
491 PRINT(
" flags %02x", hdr[1]);
502 PRINT(
" authorization-request");
505 PRINT(
" auth_method %02x", hdr[0]);
506 PRINT(
" priv_lvl %02x", hdr[1]);
507 PRINT(
" authen_type %02x", hdr[2]);
508 PRINT(
" authen_service %02x", hdr[3]);
509 PRINT(
" user_len %02x", hdr[4]);
510 PRINT(
" port_len %02x", hdr[5]);
511 PRINT(
" rem_addr_len %02x", hdr[6]);
512 PRINT(
" arg_cnt %02x", hdr[7]);
515 HEXIT(
" argc ", hdr[7]);
516 ASCII(
" user ", hdr[4]);
517 ASCII(
" port ", hdr[5]);
518 ASCII(
" rem_addr ", hdr[6]);
523 PRINT(
" authorization-reply");
529 PRINT(
" status %02x", hdr[0]);
530 PRINT(
" arg_cnt %02x", hdr[1]);
535 HEXIT(
" argc ", hdr[1]);
545 PRINT(
" accounting-request");
549 PRINT(
" flags %02x", hdr[0]);
550 PRINT(
" auth_method %02x", hdr[1]);
551 PRINT(
" priv_lvl %02x", hdr[2]);
552 PRINT(
" authen_type %02x", hdr[3]);
553 PRINT(
" authen_service %02x", hdr[4]);
554 PRINT(
" user_len %02x", hdr[5]);
555 PRINT(
" port_len %02x", hdr[6]);
556 PRINT(
" rem_addr_len %02x", hdr[7]);
557 PRINT(
" arg_cnt %02x", hdr[8]);
560 HEXIT(
" argc ", hdr[8]);
561 ASCII(
" user ", hdr[5]);
562 ASCII(
" port ", hdr[6]);
563 ASCII(
" rem_addr ", hdr[7]);
567 PRINT(
" accounting-reply");
570 PRINT(
" authentication-reply");
576 PRINT(
" status %02x", hdr[0]);
635 if ((strcmp(da->name,
"Packet") == 0) &&
650 fr_strerror_const(
"Attributes in TACACS+ cannot have assigned values. Use DEFINE, not ATTRIBUTE");
670 .default_type_size = 4,
671 .default_type_length = 4,
static int const char char buffer[256]
unsigned int name_only
this attribute should always be referred to by name.
#define fr_dict_autofree(_to_free)
unsigned int array
Pack multiples into 1 attr.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
int fr_dict_attr_autoload(fr_dict_attr_autoload_t const *to_load)
Process a dict_attr_autoload element to load/verify a dictionary attribute.
#define fr_dict_autoload(_to_load)
char const * name
name of this protocol
Specifies an attribute which must be present for the module to function.
Values of the encryption flags.
Specifies a dictionary which must be loaded/loadable for the module to function.
Protocol-specific callbacks in libfreeradius-PROTOCOL.
static uint32_t instance_count
void fr_log_hex(fr_log_t const *log, fr_log_type_t type, char const *file, int line, uint8_t const *data, size_t data_len, char const *line_prefix_fmt,...)
Print out hex block.
void fr_log(fr_log_t const *log, fr_log_type_t type, char const *file, int line, char const *fmt,...)
Send a server log message to its destination.
@ L_DBG
Only displayed when debugging is enabled.
#define MD5_DIGEST_LENGTH
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_OCTETS
Raw octets.
void fr_md5_calc(uint8_t out[static MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Perform a single digest operation on a single input buffer.
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
static uint32_t fr_nbo_to_uint32(uint8_t const data[static sizeof(uint32_t)])
Read an unsigned 32bit integer from wire format (big endian)
static fr_dict_attr_t const * attr_tacacs_authentication_flags
static fr_dict_attr_t const * attr_tacacs_user_message
static fr_dict_t const * dict_tacacs
static fr_dict_attr_t const * attr_tacacs_session_id
static fr_dict_attr_t const * attr_tacacs_server_message
static fr_dict_attr_t const * attr_tacacs_privilege_level
static fr_dict_attr_t const * attr_tacacs_authentication_type
static fr_dict_attr_t const * attr_tacacs_accounting_status
static fr_dict_attr_t const * attr_tacacs_authentication_service
static fr_dict_attr_t const * attr_tacacs_authentication_status
static fr_dict_attr_t const * attr_tacacs_client_port
static fr_dict_attr_t const * attr_tacacs_remote_address
static fr_dict_attr_t const * attr_tacacs_action
static fr_dict_attr_t const * attr_tacacs_sequence_number
static fr_dict_attr_t const * attr_tacacs_authorization_status
static fr_dict_attr_t const * attr_tacacs_accounting_flags
static fr_dict_attr_t const * attr_tacacs_data
static bool attr_valid(fr_dict_attr_t *da)
int fr_tacacs_body_xor(fr_tacacs_packet_t const *pkt, uint8_t *body, size_t body_len, char const *secret, size_t secret_len)
XOR the body based on the secret key.
fr_dict_attr_t const * attr_tacacs_length
void _fr_tacacs_packet_log_hex(fr_log_t const *log, fr_tacacs_packet_t const *packet, size_t packet_len, char const *file, int line)
fr_dict_attr_autoload_t libfreeradius_tacacs_dict_attr[]
ssize_t fr_tacacs_length(uint8_t const *buffer, size_t buffer_len)
fr_dict_attr_t const * attr_tacacs_authentication_continue_flags
char const * fr_tacacs_packet_names[FR_TACACS_CODE_MAX]
static void print_args(fr_log_t const *log, char const *file, int line, size_t arg_cnt, uint8_t const *argv, uint8_t const *start, uint8_t const *end)
void fr_tacacs_global_free(void)
static void print_hex(fr_log_t const *log, char const *file, int line, char const *prefix, uint8_t const *data, size_t datalen)
fr_dict_attr_t const * attr_tacacs_argument_list
fr_dict_attr_t const * attr_tacacs_chap_challenge
int fr_tacacs_global_init(void)
fr_dict_attr_t const * attr_tacacs_user_password
fr_dict_attr_t const * attr_tacacs_version_major
#define HEXIT(_prefix, _field)
fr_dict_autoload_t libfreeradius_tacacs_dict[]
fr_dict_attr_t const * attr_tacacs_mschap_challenge
fr_dict_protocol_t libfreeradius_tacacs_dict_protocol
fr_dict_attr_t const * attr_tacacs_mschap_response
static void print_ascii(fr_log_t const *log, char const *file, int line, char const *prefix, uint8_t const *data, size_t datalen)
fr_dict_attr_t const * attr_tacacs_version_minor
fr_dict_attr_t const * attr_tacacs_mschap2_response
fr_dict_attr_t const * attr_tacacs_chap_password
fr_dict_attr_t const * attr_tacacs_packet
fr_dict_attr_t const * attr_tacacs_packet_body_type
#define ASCII(_prefix, _field)
fr_dict_attr_t const * attr_tacacs_authentication_method
fr_dict_attr_t const * attr_tacacs_user_name
fr_dict_attr_t const * attr_tacacs_flags
fr_dict_attr_t const * attr_tacacs_packet_type
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
#define packet_is_authen_reply(p)
#define packet_is_authen_continue(p)
#define packet_is_acct_reply(p)
#define packet_is_author_request(p)
#define packet_is_acct_request(p)
#define packet_is_authen_start_request(p)
3.4.
fr_tacacs_packet_hdr_t hdr
#define packet_is_author_reply(p)
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
#define fr_strerror_const(_msg)
#define FR_TYPE_STRUCTURAL_EXCEPT_GROUP
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.