/*
* 1 == require_ma
* 2 == msg_peek
- * 3 == limit_proxy_state
+ * 4 == limit_proxy_state
+ * 8 == require_ma for Access-* replies and Protocol-Error
*/
RADIUS_PACKET *rad_recv(TALLOC_CTX *ctx, int fd, int flags);
ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, int *code);
extern bool fr_hostname_lookups; /* do hostname -> IP lookups? */
extern int fr_debug_lvl; /* 0 = no debugging information */
extern uint32_t fr_max_attributes; /* per incoming packet */
-#define FR_MAX_PACKET_CODE (52)
+#define FR_MAX_PACKET_CODE (53)
extern char const *fr_packet_codes[FR_MAX_PACKET_CODE];
#define is_radius_code(_x) ((_x > 0) && (_x < FR_MAX_PACKET_CODE))
extern FILE *fr_log_fp;
"47",
"48",
"49",
- "IP-Address-Allocate",
- "IP-Address-Release", //!< 50
+ "IP-Address-Allocate", //!< 50
+ "IP-Address-Release",
+ "Protocol-Error",
};
return rad_vp2vsa(packet, original, secret, pvp, start, room);
}
+static const bool code2ma[FR_MAX_PACKET_CODE] = {
+ [ PW_CODE_ACCESS_REQUEST ] = true,
+ [ PW_CODE_ACCESS_ACCEPT ] = true,
+ [ PW_CODE_ACCESS_REJECT ] = true,
+ [ PW_CODE_ACCESS_CHALLENGE ] = true,
+ [ PW_CODE_STATUS_SERVER ] = true,
+ [ PW_CODE_PROTOCOL_ERROR ] = true,
+};
/** Encode a packet
*
/*
* Always add Message-Authenticator for replies to
- * Access-Request packets.
+ * Access-Request packets, and for all Access-Accept,
+ * Access-Reject, Access-Challenge.
*
* It must be the FIRST attribute in the packet.
*/
- if (!packet->tls &&
- ((original && (original->code == PW_CODE_ACCESS_REQUEST)) ||
- (packet->code == PW_CODE_ACCESS_REQUEST))) {
+ if (!packet->tls &&
+ ((code2ma[packet->code]) || (original && code2ma[original->code]))) {
seen_ma = true;
packet->offset = RADIUS_HDR_LEN;
}
/*
- * Message-Authenticator is required in Status-Server
- * packets, otherwise they can be trivially forged.
+ * If the caller requires Message-Authenticator, then set
+ * the flag.
*
- * It's also required if the caller asks for it.
+ * We also require Message-Authenticator if the packet
+ * code is Status-Server.
*
+ * If we're receiving packets from a proxy socket, then
+ * require Message-Authenticator for Access-* replies,
+ * and for Protocol-Error.
+ */
+ require_ma = ((flags & 0x01) != 0) || (hdr->code == PW_CODE_STATUS_SERVER) || (((flags & 0x08) != 0) && code2ma[hdr->code]);
+
+ /*
* We only limit Proxy-State if we're not requiring
* Message-Authenticator.
*/
- require_ma = ((flags & 0x01) != 0) || (hdr->code == PW_CODE_STATUS_SERVER);
- limit_proxy_state = ((flags & 0x04) != 0) & !require_ma;
+ limit_proxy_state = ((flags & 0x04) != 0) && !require_ma;
/*
* Repeat the length checks. This time, instead of