From 2b8087801c98da91a478af14d5e6c8b87a1445dc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 16 Sep 2011 19:50:07 +0200 Subject: [PATCH] radsniff: decoding encrypted attributes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Save authentication requests and use them to properly decode entrypted attributes in matching replies. Also decode encrypted attributes in CoA requests. Some VSAs can be encrypted in CoA requests using a null vector. Signed-off-by: Bjørn Mork --- src/main/radsniff.c | 46 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/main/radsniff.c b/src/main/radsniff.c index 1132154d8df..c5d5db410d4 100644 --- a/src/main/radsniff.c +++ b/src/main/radsniff.c @@ -42,7 +42,9 @@ static int minimal = 0; static int do_sort = 0; struct timeval start_pcap = {0, 0}; static rbtree_t *filter_tree = NULL; +static rbtree_t *request_tree = NULL; static pcap_dumper_t *pcap_dumper = NULL; +static RADIUS_PACKET *nullpacket = NULL; typedef int (*rbcmp)(const void *, const void *); @@ -196,7 +198,7 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui int size_ip = sizeof(struct ip_header); int size_udp = sizeof(struct udp_header); /* For FreeRADIUS */ - RADIUS_PACKET *packet; + RADIUS_PACKET *packet, *original; struct timeval elapsed; args = args; /* -Wunused */ @@ -241,16 +243,42 @@ static void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const ui free(packet); return; } + + switch (packet->code) { + case PW_COA_REQUEST: + /* we need a 16 x 0 byte vector for decrypting encrypted VSAs */ + original = nullpacket; + break; + case PW_AUTHENTICATION_ACK: + /* look for a matching request and use it for decoding */ + original = rbtree_finddata(request_tree, packet); + break; + case PW_AUTHENTICATION_REQUEST: + /* save the request for later matching */ + original = rad_alloc_reply(packet); + if (original) { /* just ignore allocation failures */ + rbtree_deletebydata(request_tree, original); + rbtree_insert(request_tree, original); + } + /* fallthrough */ + default: + /* don't attempt to decode any encrypted attributes */ + original = NULL; + } /* * Decode the data without bothering to check the signatures. */ - if (rad_decode(packet, NULL, radius_secret) != 0) { + if (rad_decode(packet, original, radius_secret) != 0) { free(packet); fr_perror("decode"); return; } + /* we've seen a successfull reply to this, so delete it now */ + if (original) + rbtree_deletebydata(request_tree, original); + if (filter_vps && filter_packet(packet)) { free(packet); DEBUG("Packet number %d doesn't match\n", count++); @@ -453,6 +481,20 @@ int main(int argc, char *argv[]) } } + /* setup the request tree */ + request_tree = rbtree_create((rbcmp) fr_packet_cmp, free, 0); + if (!request_tree) { + fprintf(stderr, "radsniff: Failed creating request tree\n"); + exit(1); + } + + /* allocate a null packet for decrypting attributes in CoA requests */ + nullpacket = rad_alloc(0); + if (!nullpacket) { + fprintf(stderr, "radsniff: Out of memory\n"); + exit(1); + } + /* Set our device */ pcap_lookupnet(dev, &netp, &maskp, errbuf); -- 2.47.3