~yolanda.robla/ubuntu/saucy/freeradius/dep-8-tests

« back to all changes in this revision

Viewing changes to src/main/radsniff.c

  • Committer: Bazaar Package Importer
  • Author(s): Josip Rodin
  • Date: 2010-10-14 21:51:51 UTC
  • mfrom: (1.1.15 upstream)
  • Revision ID: james.westby@ubuntu.com-20101014215151-po7jgf8lyf0zq5ht
Tags: 2.1.10+dfsg-1
* New upstream version, closes a bunch of reproducible SNAFUs,
  including two tagged as security issues, CVE-2010-3696, CVE-2010-3697,
  closes: #600176.
* Build-depend on newer Libtool because of lt_dladvise_init(), also
  upstream now has a configure check so we no longer need a patch,
  yet we still don't want the old behaviour. Noticed by John Morrissey,
  closes: #584151.
* Added the /etc/default/freeradius file as suggested by
  Rudy Gevaert and Matthew Newton, closes: #564716.
* Stop symlinking /dev/urandom into /etc/freeradius/certs/random,
  it breaks grep -r in /etc. Instead, replace it inside eap.conf,
  both in the new shipped conffile and in postinst.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
static int do_sort = 0;
43
43
struct timeval start_pcap = {0, 0};
44
44
static rbtree_t *filter_tree = NULL;
 
45
static pcap_dumper_t *pcap_dumper = NULL;
 
46
 
45
47
typedef int (*rbcmp)(const void *, const void *);
46
48
 
47
49
static int filter_packet(RADIUS_PACKET *packet)
161
163
}
162
164
 
163
165
#define USEC 1000000
164
 
static void tv_sub(struct timeval *end, struct timeval *start,
 
166
static void tv_sub(const struct timeval *end, const struct timeval *start,
165
167
                   struct timeval *elapsed)
166
168
{
167
169
        elapsed->tv_sec = end->tv_sec - start->tv_sec;
200
202
        args = args;            /* -Wunused */
201
203
 
202
204
        /* Define our packet's attributes */
203
 
        ethernet = (const struct ethernet_header*)(data);
204
 
        ip = (const struct ip_header*)(data + size_ethernet);
205
 
        udp = (const struct udp_header*)(data + size_ethernet + size_ip);
206
 
        payload = (const uint8_t *)(data + size_ethernet + size_ip + size_udp);
 
205
 
 
206
        if ((data[0] == 2) && (data[1] == 0) &&
 
207
            (data[2] == 0) && (data[3] == 0)) {
 
208
                ip = (const struct ip_header*) (data + 4);
 
209
 
 
210
        } else {
 
211
                ethernet = (const struct ethernet_header*)(data);
 
212
                ip = (const struct ip_header*)(data + size_ethernet);
 
213
        }
 
214
        udp = (const struct udp_header*)(((const uint8_t *) ip) + size_ip);
 
215
        payload = (const uint8_t *)(((const uint8_t *) udp) + size_udp);
207
216
 
208
217
        packet = malloc(sizeof(*packet));
209
218
        if (!packet) {
220
229
        packet->dst_port = ntohs(udp->udp_dport);
221
230
 
222
231
        packet->data = payload;
223
 
        packet->data_len = header->len - size_ethernet - size_ip - size_udp;
 
232
        packet->data_len = header->len - (payload - data);
224
233
 
225
234
        if (!rad_packet_ok(packet, 0)) {
226
 
                fr_perror("Packet");
 
235
                printf("Packet: %s\n", fr_strerror());
227
236
                
228
 
                fprintf(stderr, "\tFrom:    %s:%d\n", inet_ntoa(ip->ip_src), ntohs(udp->udp_sport));
229
 
                fprintf(stderr, "\tTo:      %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport));
230
 
                fprintf(stderr, "\tType:    %s\n", fr_packet_codes[packet->code]);
 
237
                printf("\tFrom:    %s:%d\n", inet_ntoa(ip->ip_src), ntohs(udp->udp_sport));
 
238
                printf("\tTo:      %s:%d\n", inet_ntoa(ip->ip_dst), ntohs(udp->udp_dport));
 
239
                printf("\tType:    %s\n", fr_packet_codes[packet->code]);
231
240
 
232
241
                free(packet);
233
242
                return;
247
256
                DEBUG("Packet number %d doesn't match\n", count++);
248
257
                return;
249
258
        }
 
259
 
 
260
        if (pcap_dumper) {
 
261
                pcap_dump((void *) pcap_dumper, header, data);
 
262
                goto check_filter;
 
263
        }
 
264
 
250
265
        printf("%s Id %d\t", fr_packet_codes[packet->code], packet->id);
251
266
 
252
267
        /* Print the RADIUS packet */
272
287
        printf("\n");
273
288
        fflush(stdout);
274
289
 
 
290
 check_filter:
275
291
        /*
276
292
         *      If we're doing filtering, Access-Requests are cached
277
293
         *      in the filter tree.
290
306
        fprintf(output, "options:\n");
291
307
        fprintf(output, "\t-c count\tNumber of packets to capture.\n");
292
308
        fprintf(output, "\t-d directory\tDirectory where the dictionaries are found\n");
293
 
        fprintf(output, "\t-f filter\tPCAP filter. (default is udp port 1812 or 1813 or 1814)\n");
 
309
        fprintf(output, "\t-F\t\tFilter PCAP file from stdin to stdout.\n");
 
310
        fprintf(output, "\t\t\tOutput file will contain RADIUS packets.\n");
 
311
        fprintf(output, "\t-f filter\tPCAP filter. (default is udp port 1812 or 1813)\n");
294
312
        fprintf(output, "\t-h\t\tPrint this help message.\n");
295
313
        fprintf(output, "\t-i interface\tInterface to capture.\n");
296
314
        fprintf(output, "\t-I filename\tRead packets from filename.\n");
297
315
        fprintf(output, "\t-m\t\tPrint packet headers only, not contents.\n");
298
 
        fprintf(output, "\t-p port\tList for packets on port.\n");
 
316
        fprintf(output, "\t-p port\t\tListen for packets on port.\n");
299
317
        fprintf(output, "\t-r filter\tRADIUS attribute filter.\n");
300
318
        fprintf(output, "\t-s secret\tRADIUS secret.\n");
301
 
        fprintf(output, "\t-S\t\tSort attributes in the packet.  Used to compare server results.\n");
 
319
        fprintf(output, "\t-S\t\tSort attributes in the packet.\n");
 
320
        fprintf(output, "\t\t\tUsed to compare server results.\n");
302
321
        fprintf(output, "\t-x\t\tPrint out debugging information.\n");
303
322
        exit(status);
304
323
}
315
334
        char *pcap_filter = NULL;
316
335
        char *radius_filter = NULL;
317
336
        char *filename = NULL;
 
337
        char *dump_file = NULL;
318
338
        int packet_count = -1;          /* how many packets to sniff */
319
339
        int opt;
320
340
        FR_TOKEN parsecode;
321
341
        const char *radius_dir = RADIUS_DIR;
322
342
        int port = 1812;
 
343
        int filter_stdin = 0;
323
344
 
324
345
        /* Default device */
325
346
        dev = pcap_lookupdev(errbuf);
326
347
 
327
348
        /* Get options */
328
 
        while ((opt = getopt(argc, argv, "c:d:f:hi:I:mp:r:s:SxX")) != EOF) {
 
349
        while ((opt = getopt(argc, argv, "c:d:Ff:hi:I:mp:r:s:Sw:xX")) != EOF) {
329
350
                switch (opt)
330
351
                {
331
352
                case 'c':
338
359
                case 'd':
339
360
                        radius_dir = optarg;
340
361
                        break;
 
362
                case 'F':
 
363
                        filter_stdin = 1;
 
364
                        break;
341
365
                case 'f':
342
366
                        pcap_filter = optarg;
343
367
                        break;
365
389
                case 'S':
366
390
                        do_sort = 1;
367
391
                        break;
 
392
                case 'w':
 
393
                        dump_file = optarg;
 
394
                        break;
368
395
                case 'x':
369
396
                case 'X':       /* for backwards compatibility */
370
397
                        fr_debug_flag++;
374
401
                }
375
402
        }
376
403
 
 
404
        /*
 
405
         *      Cross-check command-line arguments.
 
406
         */
 
407
        if (filter_stdin && (filename || dump_file)) usage(1);
 
408
 
377
409
        if (!pcap_filter) {
378
410
                pcap_filter = buffer;
379
 
                snprintf(buffer, sizeof(buffer), "udp port %d or %d or %d",
380
 
                         port, port + 1, port + 2);
381
 
        }
382
 
 
383
 
        if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
384
 
                fr_perror("radsniff");
385
 
                return 1;
386
 
        }
 
411
                snprintf(buffer, sizeof(buffer), "udp port %d or %d",
 
412
                         port, port + 1);
 
413
        }
 
414
        
 
415
        /*
 
416
         *      There are many times where we don't need the dictionaries.
 
417
         */
 
418
        if (fr_debug_flag || radius_filter) {
 
419
                if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {
 
420
                        fr_perror("radsniff");
 
421
                        return 1;
 
422
                }
 
423
        }
387
424
 
388
425
        if (radius_filter) {
389
426
                parsecode = userparse(radius_filter, &filter_vps);
425
462
        /* Open the device so we can spy */
426
463
        if (filename) {
427
464
                descr = pcap_open_offline(filename, errbuf);
 
465
 
 
466
        } else if (filter_stdin) {
 
467
                descr = pcap_fopen_offline(stdin, errbuf);
 
468
 
 
469
        } else if (!dev) {
 
470
                fprintf(stderr, "radsniff: No filename or device was specified.\n");
 
471
                exit(1);
 
472
 
428
473
        } else {
429
 
                descr = pcap_open_live(dev, SNAPLEN, 1, 0, errbuf);
 
474
                descr = pcap_open_live(dev, 65536, 1, 0, errbuf);
430
475
        }
431
476
        if (descr == NULL)
432
477
        {
433
 
                printf("radsniff: pcap_open_live failed (%s)\n", errbuf);
 
478
                fprintf(stderr, "radsniff: pcap_open_live failed (%s)\n", errbuf);
434
479
                exit(1);
435
480
        }
436
481
 
 
482
        if (dump_file) {
 
483
                pcap_dumper = pcap_dump_open(descr, dump_file);
 
484
                if (!pcap_dumper) {
 
485
                        fprintf(stderr, "radsniff: Failed opening output file (%s)\n", pcap_geterr(descr));
 
486
                        exit(1);
 
487
                }
 
488
        } else if (filter_stdin) {
 
489
                pcap_dumper = pcap_dump_fopen(descr, stdout);
 
490
                if (!pcap_dumper) {
 
491
                        fprintf(stderr, "radsniff: Failed opening stdout: %s\n", pcap_geterr(descr));
 
492
                        exit(1);
 
493
                }
 
494
 
 
495
        }
 
496
 
437
497
        /* Apply the rules */
438
498
        if( pcap_compile(descr, &fp, pcap_filter, 0, netp) == -1)
439
499
        {
440
 
                printf("radsniff: pcap_compile failed\n");
 
500
                fprintf(stderr, "radsniff: pcap_compile failed\n");
441
501
                exit(1);
442
502
        }
443
503
        if (pcap_setfilter(descr, &fp) == -1)
444
504
        {
445
 
                printf("radsniff: pcap_setfilter failed\n");
 
505
                fprintf(stderr, "radsniff: pcap_setfilter failed\n");
446
506
                exit(1);
447
507
        }
448
508