27#include <freeradius-devel/util/test/acutest_common_init.h>
28#include <freeradius-devel/util/test/acutest_helpers.h>
30#include <freeradius-devel/bio/bio_priv.h>
31#include <freeradius-devel/bio/mem.h>
32#include <freeradius-devel/bio/pipe.h>
33#include <freeradius-devel/radius/bio.h>
35#define MESSAGE_AUTHENTICATOR 80
37#define MAX_PACKET_SIZE 4096
91 static uint8_t const user_name[] = { 1, 4,
'a',
'b' };
102 size_t size = in_buffer;
106 if (size_out) *size_out = size;
117 size_t size = in_buffer;
121 if (size_out) *size_out = size;
147 TEST_MSG(
"in_buffer = %zu", in_buffer);
167 TEST_CASE(
"one packet, and the start of another");
187 TEST_CASE(
"the header, and no attributes");
213 TEST_CASE(
"unknown code, followed by a valid packet");
219 if (code == 255)
break;
244 uint8_t const attrs[] = { 1, 3,
'a', 1, 3,
'b', 1, 3,
'c' };
252 TEST_CASE(
"three attributes, limit of two");
256 TEST_CASE(
"two attributes, limit of two");
275 }
const *p, bad[] = {
276#define BAD(_name, ...) { _name, (uint8_t const[]) { __VA_ARGS__ }, sizeof((uint8_t const[]) { __VA_ARGS__ }) }
277 BAD(
"attribute number zero", 0, 3,
'a'),
278 BAD(
"attribute length of zero", 1, 0,
'a'),
279 BAD(
"attribute length of one", 1, 1,
'a'),
280 BAD(
"attribute runs past the packet", 1, 9,
'a'),
281 BAD(
"a single byte after the attributes", 1, 3,
'a', 1),
282 BAD(
"Message-Authenticator is too short",
MESSAGE_AUTHENTICATOR, 10, 0, 0, 0, 0, 0, 0, 0, 0),
283 BAD(
"two Message-Authenticators",
284 MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285 MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
296 TEST_CASE(
"length field is less than a header");
302 TEST_CASE(
"Message-Authenticator is required, and missing");
307 TEST_CASE(
"Message-Authenticator is required, and present");
308 attrs = (
uint8_t const[]) {
MESSAGE_AUTHENTICATOR, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
325 for (i = 0; i <
sizeof(attrs); i += 4) {
335 TEST_CASE(
"only the header of a large packet");
341 TEST_CASE(
"a packet of exactly the maximum");
366 TEST_CASE(
"padding after the packet is not part of the packet");
367 memset(buf +
len, 0xff, 9);
378 uint8_t const attrs[] = { 1, 3,
'a', 1, 3,
'b', 1, 3,
'c' };
386 TEST_CASE(
"the length field is larger than the datagram");
389 TEST_CASE(
"the length field is less than a header");
408 TEST_CASE(
"Message-Authenticator is too short");
413 TEST_CASE(
"Message-Authenticator is required, and missing");
442 if (!source)
return NULL;
445 if (!mem)
return NULL;
457 return source->
write(source, NULL,
data, size);
480 TEST_CASE(
"the valid packet is returned");
578 TEST_CASE(
"an attribute which runs past the packet");
#define TEST_CHECK_SLEN(_got, _exp)
#define TEST_CHECK_LEN(_got, _exp)
fr_bio_write_t _CONST write
write to the underlying bio
static ssize_t fr_bio_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
Read raw data from a bio.
fr_bio_io_t read_resume
"unblocked" is too similar to "blocked"
@ FR_RADIUS_CODE_ACCESS_REQUEST
RFC2865 - Access-Request.
@ FR_RADIUS_CODE_MAX
Maximum possible protocol code.
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
@ FR_RADIUS_CODE_ACCOUNTING_RESPONSE
RFC2866 - Accounting-Response.
fr_bio_t * fr_bio_mem_alloc(TALLOC_CTX *ctx, size_t read_size, size_t write_size, fr_bio_t *next)
Allocate a memory buffer bio.
int fr_bio_mem_set_verify(fr_bio_t *bio, fr_bio_verify_t verify, void *verify_ctx, bool datagram)
Set the verification function for memory bios.
fr_bio_verify_action_t
Status returned by the verification callback.
@ FR_BIO_VERIFY_ERROR_CLOSE
fatal error, the bio should be closed.
@ FR_BIO_VERIFY_DISCARD
the packet should be discarded
@ FR_BIO_VERIFY_OK
packet is OK
@ FR_BIO_VERIFY_WANT_MORE
not enough data for one packet
#define RADIUS_HEADER_LENGTH
fr_bio_t * fr_bio_pipe_alloc(TALLOC_CTX *ctx, fr_bio_cb_funcs_t *cb, size_t buffer_size)
Allocate a thread-safe pipe which can be used for both reads and writes.
fr_bio_verify_action_t fr_radius_bio_verify_datagram(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size)
And verify a datagram packet.
fr_bio_verify_action_t fr_radius_bio_verify(UNUSED fr_bio_t *bio, void *verify_ctx, UNUSED void *packet_ctx, const void *data, size_t *size)
Callback for RADIUS packet verification.
bool require_message_authenticator
static void test_stream_unknown_code(void)
A packet with a code which the module does not know is skipped, and the packets after it are kept.
static size_t make_packet(uint8_t *out, uint8_t code, uint8_t const *attrs, size_t attrs_len)
Build a packet with a header, and the given attributes.
static void cb_noop_void(fr_bio_t *bio)
static fr_bio_cb_funcs_t test_cb
static void test_stream_partial_packet(void)
A packet which is not all in the buffer asks for the rest of the packet.
static void test_stream_one_packet(void)
A complete packet is returned, and only that packet.
#define MESSAGE_AUTHENTICATOR
static void test_stream_not_allowed(void)
A packet with a code which is known, but not allowed, is skipped.
static void test_mem_fatal(void)
A packet which cannot be skipped fails the read.
static fr_radius_bio_verify_t test_ctx(void)
Make a verify context which allows Access-Request and Access-Accept.
static void test_mem_two_packets(void)
Packets which arrive together are returned one at a time.
static fr_bio_verify_action_t datagram_verify(fr_radius_bio_verify_t *ctx, uint8_t const *buf, size_t in_buffer, size_t *size_out)
Call the datagram verify callback on a buffer holding in_buffer bytes.
static void test_datagram_discard(void)
A datagram which is not a good packet is discarded, and never closes the socket.
static void test_stream_too_many_attributes(void)
A packet with more attributes than the limit is skipped, and the packets after it are kept.
static fr_bio_verify_action_t stream_verify(fr_radius_bio_verify_t *ctx, uint8_t const *buf, size_t in_buffer, size_t *size_out)
Call the stream verify callback on a buffer holding in_buffer bytes.
static void test_datagram_one_packet(void)
A datagram holds one packet, and trailing bytes are padding.
static size_t make_valid(uint8_t *out, uint8_t code)
Make a packet whose attributes are a User-Name of "ab".
static void test_mem_split_packet(void)
A packet which arrives in pieces is returned when the packet is complete, and the connection stays op...
static void test_stream_fatal(void)
Errors which leave the stream without a known start of the next packet close the connection.
static fr_bio_t * test_mem_alloc(TALLOC_CTX *ctx, fr_bio_t **source_p, fr_radius_bio_verify_t *vctx)
A memory bio in front of a pipe, which stands in for the network.
static void test_stream_too_large(void)
A packet which is larger than the module allows closes the connection, even when only the header has ...
static ssize_t test_source_write(fr_bio_t *source, uint8_t const *data, size_t size)
Put bytes where the memory bio's reads will find them.
static void test_mem_unknown_code_keeps_next_packet(void)
A packet which the module does not accept does not take the packets after it.
static void test_stream_short_buffer(void)
A buffer which holds less than a header asks for the header.
static int cb_noop(fr_bio_t *bio)
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
static fr_sbuff_err_t char size_t fr_sbuff_t * in
static fr_sbuff_err_t char ** out
static fr_sbuff_err_t char size_t * len