]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
radsniff: decoding encrypted attributes
authorBjørn Mork <bjorn@mork.no>
Fri, 16 Sep 2011 17:50:07 +0000 (19:50 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 19 Sep 2011 12:09:42 +0000 (14:09 +0200)
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 <bjorn@mork.no>
src/main/radsniff.c

index 1132154d8dfe044cfa07e519263a63c0c0b0fc4c..c5d5db410d469a233b9c387b6a571c2278cd4b62 100644 (file)
@@ -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);