From: Arran Cudbard-Bell Date: Wed, 22 Apr 2020 23:17:48 +0000 (-0500) Subject: radius-encode: Change some contentious behaviour X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=44a34c9aa22efdaccfb9b2fff8aa834d30007028;p=thirdparty%2Ffreeradius-server.git radius-encode: Change some contentious behaviour - Rework encrypted password functions to use a more common signature - Skip encoding values greater than 253 bytes - Don't use intermediary buffer when encoding fixed length values, write them directly to the output buffer - Return the number of bytes we would have needed when encoding attribute values. - Fix struct TLV encoding as it didn't advance the output buffer pointer. - Write the tag byte for all types if the VP says we should. - Allow encoding of floats --- diff --git a/src/protocols/radius/base.c b/src/protocols/radius/base.c index 6e3fc3c8b0d..16bc14d84b2 100644 --- a/src/protocols/radius/base.c +++ b/src/protocols/radius/base.c @@ -236,18 +236,33 @@ size_t fr_radius_attr_len(VALUE_PAIR const *vp) * We put them into MD5 in the reverse order from that used when * encrypting passwords to RADIUS. */ -void fr_radius_ascend_secret(uint8_t *digest, uint8_t const *vector, char const *secret, uint8_t const *value) +ssize_t fr_radius_ascend_secret(uint8_t *out, size_t outlen, uint8_t const *in, size_t inlen, + char const *secret, uint8_t const *vector) { fr_md5_ctx_t *md5_ctx; int i; + uint8_t buff[RADIUS_AUTH_VECTOR_LENGTH]; + + if (outlen < RADIUS_AUTH_VECTOR_LENGTH) return -(outlen - RADIUS_AUTH_VECTOR_LENGTH); + + /* + * Probably shouldn't happen, but deal with it gracefully if it does + */ + if (inlen < RADIUS_AUTH_VECTOR_LENGTH) { + memset(buff, 0, sizeof(buff)); + memcpy(buff, in, inlen); + in = buff; + } md5_ctx = fr_md5_ctx_alloc(true); fr_md5_update(md5_ctx, vector, RADIUS_AUTH_VECTOR_LENGTH); fr_md5_update(md5_ctx, (uint8_t const *) secret, talloc_array_length(secret) - 1); - fr_md5_final(digest, md5_ctx); + fr_md5_final(out, md5_ctx); fr_md5_ctx_free(&md5_ctx); - for (i = 0; i < RADIUS_AUTH_VECTOR_LENGTH; i++ ) digest[i] ^= value[i]; + for (i = 0; i < RADIUS_AUTH_VECTOR_LENGTH; i++ ) out[i] ^= in[i]; + + return RADIUS_AUTH_VECTOR_LENGTH; } /** Basic validation of RADIUS packet header diff --git a/src/protocols/radius/decode.c b/src/protocols/radius/decode.c index 2c95bfb577d..52eaf88d31c 100644 --- a/src/protocols/radius/decode.c +++ b/src/protocols/radius/decode.c @@ -1135,7 +1135,8 @@ ssize_t fr_radius_decode_pair_value(TALLOC_CTX *ctx, fr_cursor_t *cursor, fr_dic * Ascend-Receive-Secret */ case FLAG_ENCRYPT_ASCEND_SECRET: - fr_radius_ascend_secret(buffer, packet_ctx->vector, packet_ctx->secret, p); + fr_radius_ascend_secret(buffer, sizeof(buffer), p, data_len, + packet_ctx->secret, packet_ctx->vector); buffer[RADIUS_AUTH_VECTOR_LENGTH] = '\0'; data_len = strlen((char *) buffer); break; diff --git a/src/protocols/radius/encode.c b/src/protocols/radius/encode.c index 93c7cdbbc38..620be2dd76d 100644 --- a/src/protocols/radius/encode.c +++ b/src/protocols/radius/encode.c @@ -79,9 +79,12 @@ void fr_radius_encode_chap_password(uint8_t out[static 1 + RADIUS_CHAP_CHALLENGE fr_md5_ctx_free(&md5_ctx); } - -static void encode_password(uint8_t *out, ssize_t *outlen, uint8_t const *input, size_t inlen, - char const *secret, uint8_t const *vector) +/** "encrypt" a password RADIUS style + * + * Input and output buffers can be identical if in-place encryption is needed. + */ +static ssize_t encode_password(uint8_t *out, ssize_t outlen, uint8_t const *input, size_t inlen, + char const *secret, uint8_t const *vector) { fr_md5_ctx_t *md5_ctx, *md5_ctx_old; uint8_t digest[RADIUS_AUTH_VECTOR_LENGTH]; @@ -130,42 +133,47 @@ static void encode_password(uint8_t *out, ssize_t *outlen, uint8_t const *input, fr_md5_ctx_free(&md5_ctx_old); /* - * Truncate it as necessary. + * Return how many bytes we would have needed */ - if (len > (size_t) *outlen) { - len = *outlen; - } else { - *outlen = len; - } + if (len > (size_t) outlen) return -(len - outlen); memcpy(out, passwd, len); + + return len; } -static void encode_tunnel_password(uint8_t *out, ssize_t *outlen, - uint8_t const *input, size_t inlen, size_t freespace, - void *encoder_ctx) +static ssize_t encode_tunnel_password(uint8_t *out, size_t outlen, + uint8_t const *in, size_t inlen, void *encoder_ctx) { fr_md5_ctx_t *md5_ctx, *md5_ctx_old; uint8_t digest[RADIUS_AUTH_VECTOR_LENGTH]; + uint8_t tpasswd[RADIUS_MAX_STRING_LENGTH]; size_t i, n; size_t encrypted_len; fr_radius_ctx_t *packet_ctx = encoder_ctx; uint32_t r; + size_t len; /* * The password gets encoded with a 1-byte "length" * field. Ensure that it doesn't overflow. */ - if (freespace > 253) freespace = 253; + if (outlen > RADIUS_MAX_STRING_LENGTH) outlen = RADIUS_MAX_STRING_LENGTH; /* - * Limit the maximum size of the input password. 2 bytes + * Limit the maximum size of the in password. 2 bytes * are taken up by the salt, and one by the encoded * "length" field. Note that if we have a tag, the - * "freespace" will be 252 octets, not 253 octets. + * "outlen" will be 252 octets, not 253 octets. + */ + if (inlen > (RADIUS_MAX_STRING_LENGTH - 3)) inlen = (RADIUS_MAX_STRING_LENGTH - 3); + + /* + * If we still overflow the output, let the caller know + * how many bytes would have been needed. */ - if (inlen > (freespace - 3)) inlen = freespace - 3; + if (inlen > (outlen - 3)) return -(inlen - (outlen - 3)); /* * Length of the encrypted data is the clear-text @@ -184,17 +192,17 @@ static void encode_tunnel_password(uint8_t *out, ssize_t *outlen, * We need 2 octets for the salt, followed by the actual * encrypted data. */ - if (encrypted_len > (freespace - 2)) encrypted_len = freespace - 2; + if (encrypted_len > (outlen - 2)) encrypted_len = outlen - 2; - *outlen = encrypted_len + 2; /* account for the salt */ + len = encrypted_len + 2; /* account for the salt */ /* * Copy the password over, and fill the remainder with random data. */ - memcpy(out + 3, input, inlen); + memcpy(tpasswd + 3, in, inlen); - for (i = 3 + inlen; i < (size_t) *outlen; i++) { - out[i] = fr_fast_rand(&packet_ctx->rand_ctx); + for (i = 3 + inlen; i < (size_t)len; i++) { + tpasswd[i] = fr_fast_rand(&packet_ctx->rand_ctx); } /* @@ -207,9 +215,9 @@ static void encode_tunnel_password(uint8_t *out, ssize_t *outlen, * add in some PRNG data. should be OK.. */ r = fr_fast_rand(&packet_ctx->rand_ctx); - out[0] = (0x80 | (((packet_ctx->salt_offset++) & 0x07) << 4) | ((r >> 8) & 0x0f)); - out[1] = r & 0xff; - out[2] = inlen; /* length of the password string */ + tpasswd[0] = (0x80 | (((packet_ctx->salt_offset++) & 0x07) << 4) | ((r >> 8) & 0x0f)); + tpasswd[1] = r & 0xff; + tpasswd[2] = inlen; /* length of the password string */ md5_ctx = fr_md5_ctx_alloc(false); md5_ctx_old = fr_md5_ctx_alloc(true); @@ -218,28 +226,32 @@ static void encode_tunnel_password(uint8_t *out, ssize_t *outlen, fr_md5_ctx_copy(md5_ctx_old, md5_ctx); fr_md5_update(md5_ctx, packet_ctx->vector, RADIUS_AUTH_VECTOR_LENGTH); - fr_md5_update(md5_ctx, &out[0], 2); + fr_md5_update(md5_ctx, &tpasswd[0], 2); for (n = 0; n < encrypted_len; n += AUTH_PASS_LEN) { size_t block_len; if (n > 0) { fr_md5_ctx_copy(md5_ctx, md5_ctx_old); - fr_md5_update(md5_ctx, out + 2 + n - AUTH_PASS_LEN, AUTH_PASS_LEN); + fr_md5_update(md5_ctx, tpasswd + 2 + n - AUTH_PASS_LEN, AUTH_PASS_LEN); } fr_md5_final(digest, md5_ctx); - if ((2 + n + AUTH_PASS_LEN) < freespace) { + if ((2 + n + AUTH_PASS_LEN) < outlen) { block_len = AUTH_PASS_LEN; } else { - block_len = freespace - 2 - n; + block_len = outlen - 2 - n; } - for (i = 0; i < block_len; i++) out[i + 2 + n] ^= digest[i]; + for (i = 0; i < block_len; i++) tpasswd[i + 2 + n] ^= digest[i]; } fr_md5_ctx_free(&md5_ctx); fr_md5_ctx_free(&md5_ctx_old); + + memcpy(out, tpasswd, len); + + return len; } static ssize_t encode_tlv_hdr_internal(uint8_t *out, size_t outlen, @@ -342,15 +354,16 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, fr_da_stack_t *da_stack, unsigned int depth, fr_cursor_t *cursor, void *encoder_ctx) { - size_t offset; - ssize_t len; - uint8_t const *data = NULL; - uint8_t *ptr = out; - uint8_t buffer[64]; + ssize_t slen; + size_t len; VALUE_PAIR const *vp = fr_cursor_current(cursor); fr_dict_attr_t const *da = da_stack->da[depth]; fr_radius_ctx_t *packet_ctx = encoder_ctx; + uint8_t *out_p = out; + uint8_t *out_end = out + outlen; + uint8_t *value_start = out_p; + VP_VERIFY(vp); FR_PROTO_STACK_PRINT(da_stack, depth); @@ -359,31 +372,27 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, */ if (!vp->da->flags.extra && (vp->da->flags.subtype != FLAG_EXTENDED_ATTR) && !packet_ctx) { fr_strerror_printf("Asked to encrypt attribute, but no packet context provided"); - return -1; + return PAIR_ENCODE_FATAL_ERROR; } /* * It's a little weird to consider a TLV as a value, * but it seems to work OK. */ - if (da->type == FR_TYPE_TLV) { - return encode_tlv_hdr(out, outlen, da_stack, depth, cursor, encoder_ctx); - } + if (da->type == FR_TYPE_TLV) return encode_tlv_hdr(out_p, out_end - out_p, + da_stack, depth, cursor, encoder_ctx); /* * This has special requirements. */ if (da->type == FR_TYPE_STRUCT) { - ssize_t struct_len; - - struct_len = fr_struct_to_network(out, outlen, da_stack, depth, cursor, encoder_ctx, encode_value); - if (struct_len <= 0) return struct_len; + slen = fr_struct_to_network(out_p, out_end - out_p, da_stack, depth, cursor, encoder_ctx, encode_value); + if (slen <= 0) return slen; vp = fr_cursor_current(cursor); fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); - out += struct_len; - outlen -= struct_len; + out_p += slen; /* * Encode any TLV, attributes which are part of this structure. @@ -397,17 +406,17 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, * TLV to be encoded here. It's number is just * the field number in the struct. */ - while (vp && (da_stack->da[depth] == da) && (da_stack->depth >= da->depth) && (outlen > 0)) { - len = encode_tlv_hdr_internal(out, outlen, da_stack, depth + 1, cursor, encoder_ctx); - if (len < 0) return len; + while (vp && (da_stack->da[depth] == da) && (da_stack->depth >= da->depth) && (out_p < out_end)) { + slen = encode_tlv_hdr_internal(out_p, out_end - out_p, da_stack, depth + 1, cursor, encoder_ctx); + if (slen < 0) return slen; - struct_len += len; + out_p += slen; vp = fr_cursor_current(cursor); fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); } - return struct_len; + return out_p - out; } /* @@ -416,29 +425,49 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, */ if (da_stack->da[depth + 1] != NULL) { fr_strerror_printf("%s: Encoding value but not at top of stack", __FUNCTION__); - return -1; + return PAIR_ENCODE_FATAL_ERROR; } if (vp->da != da) { fr_strerror_printf("%s: Top of stack does not match vp->da", __FUNCTION__); - return -1; + return PAIR_ENCODE_FATAL_ERROR; } switch (da->type) { case FR_TYPE_STRUCTURAL: fr_strerror_printf("%s: Called with structural type %s", __FUNCTION__, fr_table_str_by_value(fr_value_box_type_table, da_stack->da[depth]->type, "?Unknown?")); - return -1; + return PAIR_ENCODE_FATAL_ERROR; default: break; } + /* + * Write tag byte + */ + if (vp->da->flags.has_tag && TAG_VALID(vp->tag)) { + CHECK_FREESPACE(out_end - out_p, 1); + *out_p++ = vp->tag; + value_start = out_p; + } + /* * Set up the default sources for the data. */ len = fr_radius_attr_len(vp); + /* + * Invalid value, don't encode. + */ + if (len > RADIUS_MAX_STRING_LENGTH) return 0; + + /* + * For everything else, return the number of + * additional bytes we need. + */ + CHECK_FREESPACE(out_end - out_p, len); + switch (da->type) { /* * If asked to encode more data than allowed, we @@ -446,41 +475,45 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, */ case FR_TYPE_OCTETS: case FR_TYPE_STRING: - data = vp->vp_ptr; + memcpy(out_p, vp->vp_ptr, len); + out_p += len; break; case FR_TYPE_ABINARY: - data = vp->vp_filter; + memcpy(out_p, vp->vp_filter, len); + out_p += len; break; /* * Common encoder might add scope byte */ case FR_TYPE_IPV6_ADDR: - memcpy(buffer, vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr)); - data = buffer; + memcpy(out_p, vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr)); + out_p += len; break; /* * Common encoder doesn't add reserved byte */ case FR_TYPE_IPV6_PREFIX: - buffer[0] = 0; - buffer[1] = vp->vp_ip.prefix; - len = vp->vp_ip.prefix >> 3; /* Convert bits to whole bytes */ - memcpy(buffer + 2, vp->vp_ipv6addr, len); /* Only copy the minimum number of address bytes required */ - len += 2; /* Reserved and prefix bytes */ - data = buffer; + len = vp->vp_ip.prefix >> 3; /* Convert bits to whole bytes */ + + CHECK_FREESPACE(out_end - out_p, 2 + len); + + *out_p++ = 0; + *out_p++ = vp->vp_ip.prefix; + memcpy(out_p, vp->vp_ipv6addr, len); /* Only copy the minimum number of address bytes required */ + out_p += len; break; /* * Common encoder doesn't add reserved byte */ case FR_TYPE_IPV4_PREFIX: - buffer[0] = 0; - buffer[1] = vp->vp_ip.prefix; - memcpy(buffer + 2, &vp->vp_ipv4addr, sizeof(vp->vp_ipv4addr)); - data = buffer; + *out_p++ = 0; + *out_p++ = vp->vp_ip.prefix; + memcpy(out_p, &vp->vp_ipv4addr, sizeof(vp->vp_ipv4addr)); + out_p += sizeof(vp->vp_ipv4addr); break; /* @@ -498,11 +531,18 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, case FR_TYPE_INT16: case FR_TYPE_INT32: case FR_TYPE_INT64: + case FR_TYPE_FLOAT32: /* Not officially defined in a RADIUS RFC */ + case FR_TYPE_FLOAT64: /* Not officially defined in a RADIUS RFC */ case FR_TYPE_DATE: case FR_TYPE_TIME_DELTA: - len = fr_value_box_to_network(NULL, buffer, sizeof(buffer), &vp->data); - if (len < 0) return -1; - data = buffer; + { + size_t need = 0; + + slen = fr_value_box_to_network(&need, out_p, out_end - out_p, &vp->data); + if (slen < 0) return slen; + if (need > 0) return -(need); + out_p += slen; + } break; case FR_TYPE_INVALID: @@ -514,29 +554,28 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, case FR_TYPE_TLV: case FR_TYPE_STRUCT: case FR_TYPE_SIZE: - case FR_TYPE_FLOAT32: - case FR_TYPE_FLOAT64: case FR_TYPE_GROUP: case FR_TYPE_VALUE_BOX: case FR_TYPE_MAX: fr_strerror_printf("Unsupported attribute type %d", da->type); - return -1; + return PAIR_ENCODE_FATAL_ERROR; } /* * No data: don't encode the value. The type and length should still * be written. */ - if (!data || (len == 0)) { + if (out_p == out) { vp = fr_cursor_next(cursor); fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); return 0; } /* - * Bind the data to the calling size + * Shouldn't happen, but if it does return how much + * the overrun was. */ - if (len > (ssize_t)outlen) len = outlen; + if (!fr_cond_assert(out_p <= out_end)) return -((out_end - out_p) + 1); /* * Encrypt the various password styles @@ -546,61 +585,78 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, */ if (!da->flags.extra) switch (vp->da->flags.subtype) { case FLAG_ENCRYPT_USER_PASSWORD: - encode_password(ptr, &len, data, len, packet_ctx->secret, packet_ctx->vector); + { + uint8_t *value_end = out_p; + + out_p = value_start; /* Reset */ + + /* + * Encode the password in place + */ + slen = encode_password(out_p, out_end - out_p, + value_start, value_end - value_start, + packet_ctx->secret, packet_ctx->vector); + if (slen < 0) return slen; + + out_p += slen; + } break; case FLAG_ENCRYPT_TUNNEL_PASSWORD: - offset = 0; - if (da->flags.has_tag) offset = 1; + { + uint8_t *value_end = out_p; + + out_p = value_start; /* Reset */ /* - * Check if there's enough freespace. If there isn't, - * we discard the attribute. + * Hack - Always encode the tag even if it's zero. * - * This is ONLY a problem if we have multiple VSA's - * in one Vendor-Specific, though. + * Not sure why we do this, but the old code did... */ - if (outlen < (18 + offset)) return 0; + if (vp->da->flags.has_tag && !TAG_VALID(vp->tag)) out_p++; - if (offset) ptr[0] = TAG_VALID(vp->tag) ? vp->tag : TAG_NONE; - - encode_tunnel_password(ptr + offset, &len, data, len, - outlen - offset, packet_ctx); - len += offset; - break; + slen = encode_tunnel_password(out_p, out_end - out_p, + value_start, value_end - value_start, packet_ctx); + if (slen < 0) { + /* + * This is an un-encodable tunnel_password_attribute + */ + if (outlen >= RADIUS_MAX_STRING_LENGTH) return 0; + return slen; + } /* - * The code above ensures that this attribute - * always fits. + * Do this after so we don't mess up the input + * value. */ - case FLAG_ENCRYPT_ASCEND_SECRET: - if (len != 16) return 0; + if (vp->da->flags.has_tag && !TAG_VALID(vp->tag)) *value_start = 0x00; - fr_radius_ascend_secret(ptr, packet_ctx->vector, packet_ctx->secret, data); - len = RADIUS_AUTH_VECTOR_LENGTH; + out_p += slen; + } break; - /* - * Not encrypted, OR an extended attribute, which - * cannot be encrypted. - */ - default: - if (vp->da->flags.has_tag && TAG_VALID(vp->tag)) { - if (vp->vp_type == FR_TYPE_STRING) { - if (len > ((ssize_t) (outlen - 1))) len = outlen - 1; - ptr[0] = vp->tag; - ptr++; - } else if (vp->vp_type == FR_TYPE_UINT32) { - buffer[0] = vp->tag; - } /* else it can't be any other type */ - } - memcpy(ptr, data, len); + /* + * The code above ensures that this attribute + * always fits. + */ + case FLAG_ENCRYPT_ASCEND_SECRET: + { + uint8_t *value_end = out_p; + + out_p = value_start; /* Reset */ + + slen = fr_radius_ascend_secret(out_p, out_end - out_p, + value_start, value_end - value_start, + packet_ctx->secret, packet_ctx->vector); + if (slen < 0) return slen; + out_p += slen; + + } break; - } else { - memcpy(ptr, data, len); } - FR_PROTO_HEX_DUMP(out, len, "value %s", fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "")); + FR_PROTO_HEX_DUMP(out, out_p - out, "value %s", + fr_table_str_by_value(fr_value_box_type_table, vp->vp_type, "")); /* * Rebuilds the TLV stack for encoding the next attribute @@ -608,7 +664,7 @@ static ssize_t encode_value(uint8_t *out, size_t outlen, vp = fr_cursor_next(cursor); fr_proto_da_stack_build(da_stack, vp ? vp->da : NULL); - return len + (ptr - out); + return out_p - out; } static ssize_t attr_shift(uint8_t const *start, uint8_t const *end, diff --git a/src/protocols/radius/radius.h b/src/protocols/radius/radius.h index 3d0c3e4accc..72c841682c2 100644 --- a/src/protocols/radius/radius.h +++ b/src/protocols/radius/radius.h @@ -99,8 +99,8 @@ int fr_radius_verify(uint8_t *packet, uint8_t const *original, bool fr_radius_ok(uint8_t const *packet, size_t *packet_len_p, uint32_t max_attributes, bool require_ma, decode_fail_t *reason) CC_HINT(nonnull (1,2)); -void fr_radius_ascend_secret(uint8_t *digest, uint8_t const *vector, - char const *secret, uint8_t const *value) CC_HINT(nonnull); +ssize_t fr_radius_ascend_secret(uint8_t *out, size_t outlen, uint8_t const *in, size_t inlen, + char const *secret, uint8_t const *vector); ssize_t fr_radius_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, unsigned int *code); diff --git a/src/tests/unit/protocols/radius/truncate.txt b/src/tests/unit/protocols/radius/truncate.txt index 9296ee95947..19e00b2e535 100644 --- a/src/tests/unit/protocols/radius/truncate.txt +++ b/src/tests/unit/protocols/radius/truncate.txt @@ -4,20 +4,28 @@ proto radius proto-dictionary radius -max_packet_size 32 +# +# Torture tests for various types +# +encode-pair truncate User-Name = "0123456789" +match 01 0c 30 31 32 33 34 35 36 37 38 39 +returned +match 12 + +max-buffer-size 32 match 32 +# Need 63 bytes, we have 32 so we should get back -31 encode-pair User-Name = "0123456789a123456789b123456789c123456789d123456789e123456789f" -match 01 20 30 31 32 33 34 35 36 37 38 39 61 31 32 33 34 35 36 37 38 39 62 31 32 33 34 35 36 37 38 39 - -decode-pair - -match User-Name = "0123456789a123456789b123456789" +match +returned +match -31 +# Need 63 bytes, we have 32 so we should get back -31 encode-pair User-Password = "0123456789a123456789b123456789c123456789d123456789e123456789f" -match 02 20 a6 df 3b f9 40 c8 4c 2d 28 7f 66 15 32 27 b6 be dc 8f f1 2a 7f cc b6 58 f9 d1 08 64 6b d2 - -decode-pair - -match User-Password = "0123456789a123456789b123456789" +match +returned +match -31 count -match 12 +match 16 diff --git a/src/tests/unit/protocols/radius/tunnel.txt b/src/tests/unit/protocols/radius/tunnel.txt index a315ce2fffd..018c8ef7a6f 100644 --- a/src/tests/unit/protocols/radius/tunnel.txt +++ b/src/tests/unit/protocols/radius/tunnel.txt @@ -85,9 +85,18 @@ match Tunnel-Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 1 octet for the tag. 2 octets for salt. One octet for encrypted length. # 249 octets left for real data. # -encode-pair Tunnel-Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123456789ab" +encode-pair Tunnel-Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123456789" decode-pair - match Tunnel-Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123456789" +# +# 250 octets results in the attribute being skipped as there's no way we +# can represent this value. +# +encode-pair Tunnel-Password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx123456789a" +match +returned +match 0 + count -match 59 +match 63