not from the encrypted packet.
fr_io_track_t const *track = talloc_get_type_abort_const(request->async->packet_ctx, fr_io_track_t);
fr_io_address_t const *address = track->address;
RADCLIENT const *client;
- int code;
+ int code = -1;
fr_tacacs_packet_t const *pkt = (fr_tacacs_packet_t const *)data;
char const *secret;
size_t secretlen = 0;
return -1;
}
- /*
- * RFC 8907 Section 3.6 says:
- *
- * If an error occurs but the type of the incoming packet cannot be determined, a packet with the
- * identical cleartext header but with a sequence number incremented by one and the length set to
- * zero MUST be returned to indicate an error.
- *
- * This is substantially retarded. It should instead just close the connection.
- */
-
- code = fr_tacacs_packet_to_code(pkt);
- if (code < 0) {
- RPEDEBUG("Invalid packet");
- return -1;
- }
-
- request->packet->code = code;
request->packet->id = data[2]; // seq_no
request->reply->id = data[2]; // seq_no
*/
if (fr_tacacs_decode(request->request_ctx, &request->request_pairs,
request->packet->data, request->packet->data_len,
- NULL, secret, secretlen) < 0) {
+ NULL, secret, secretlen, &code) < 0) {
RPEDEBUG("Failed decoding packet");
return -1;
}
+ request->packet->code = code;
+
+ /*
+ * RFC 8907 Section 3.6 says:
+ *
+ * If an error occurs but the type of the incoming packet cannot be determined, a packet with the
+ * identical cleartext header but with a sequence number incremented by one and the length set to
+ * zero MUST be returned to indicate an error.
+ *
+ * This is substantially retarded. It should instead just close the connection.
+ */
+
+
/*
* Set the rest of the fields.
*/
* - >0 for how many bytes were decoded
*/
static ssize_t decode(TALLOC_CTX *ctx, fr_pair_list_t *reply, uint8_t *response_code,
- udp_handle_t *h, request_t *request, udp_request_t *u,
- uint8_t *data, size_t data_len)
+ udp_handle_t *h, request_t *request, udp_request_t *u,
+ uint8_t *data, size_t data_len)
{
rlm_tacacs_tcp_t const *inst = h->thread->inst;
ssize_t packet_len;
- uint8_t code;
+ int code;
*response_code = 0; /* Initialise to keep the rest of the code happy */
* This only fails if the packet is strangely malformed,
* or if we run out of memory.
*/
- packet_len = fr_tacacs_decode(ctx, reply, data, data_len, NULL, inst->secret, inst->secretlen);
+ packet_len = fr_tacacs_decode(ctx, reply, data, data_len, NULL, inst->secret, inst->secretlen, &code);
if (packet_len < 0) {
RPEDEBUG("Failed decoding TACACS+ reply packet");
fr_pair_list_free(reply);
return -1;
}
- code = data[1];
-
RDEBUG("Received %s ID %d length %ld reply packet on connection %s",
fr_tacacs_packet_names[code], code, packet_len, h->name);
log_request_pair_list(L_DBG_LVL_2, request, NULL, reply, NULL);
* Decode a TACACS+ packet
*/
ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *buffer, size_t buffer_len,
- const uint8_t *original, char const * const secret, size_t secret_len)
+ const uint8_t *original, char const * const secret, size_t secret_len, int *code)
{
fr_tacacs_packet_t const *pkt;
fr_pair_t *vp;
decrypted[3] |= FR_TAC_PLUS_UNENCRYPTED_FLAG;
FR_PROTO_HEX_DUMP(decrypted, buffer_len, "fr_tacacs_packet_t (unencrypted)");
+
+ if (code) {
+ *code = fr_tacacs_packet_to_code((fr_tacacs_packet_t const *) decrypted);
+ if (*code < 0) return -1;
+ }
}
#ifndef NDEBUG
fr_tacacs_ctx_t *test_ctx = talloc_get_type_abort(proto_ctx, fr_tacacs_ctx_t);
return fr_tacacs_decode(ctx, out, data, data_len, NULL,
- test_ctx->secret, (talloc_array_length(test_ctx->secret)-1));
+ test_ctx->secret, (talloc_array_length(test_ctx->secret)-1), false);
}
static int _encode_test_ctx(fr_tacacs_ctx_t *proto_ctx)
/* decode.c */
ssize_t fr_tacacs_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *buffer, size_t buffer_len,
- UNUSED const uint8_t *original, char const * const secret, size_t secret_len);
+ UNUSED const uint8_t *original, char const * const secret, size_t secret_len, int *code);
int fr_tacacs_packet_to_code(fr_tacacs_packet_t const *pkt);