~ubuntu-branches/ubuntu/natty/freeradius/natty-updates

« back to all changes in this revision

Viewing changes to src/lib/vqp.c

  • Committer: Bazaar Package Importer
  • Author(s): Josip Rodin
  • Date: 2009-11-23 03:57:37 UTC
  • mfrom: (1.2.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20091123035737-zsgtzhfych8hir68
Tags: 2.1.7+dfsg-1
* Adopting the package, closes: #536623.
* New upstream version, closes: #513484.
  + Fixes the blooper in unlang evaluation logic, closes: #526175.
* Used quilt (and added README.source), and moved upstream file patching
  into debian/patches/. The source is no longer in collab-maint git
  (to make it simpler for me to finally get this out the door), but
  kept the .gitignore should we need that again.
* Dropped the dialup_admin/bin/backup_radacct patch (integrated upstream).
* Dropped the raddb/Makefile patch (problem no longer exists upstream).
* Dropped the lib/packet.c lib/radius.c main/listen.c patches (was from
  upstream 2.0.5 anyway).
* Dropped references to otp.conf, it no longer exists upstream.
  Keep removing the conffile statoverride in prerm.
* Dropped references to snmp.conf, it no longer exists upstream.
  Keep removing the conffile statoverride in prerm.
* Ship /etc/freeradius/modules/* in the freeradius package.
* Stop shipping sites-enabled symlinks in the package and instead create
  them only on initial install, thanks to Matej Vela, closes: #533396.
* Add export PATH="${PATH:+$PATH:}/usr/sbin:/sbin" to the init script
  at the request of John Morrissey, closes: #550143.
* Stop installing /var/run/freeradius in the package to silence Lintian.
  The init script already recreates it at will.
* Remove executable bit from example.pl to silence Lintian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * vqp.c        Functions to send/receive VQP packets.
3
3
 *
4
 
 * Version:     $Id: vqp.c,v 1.4 2008/01/05 17:58:44 nbk Exp $
 
4
 * Version:     $Id$
5
5
 *
6
6
 *   This library is free software; you can redistribute it and/or
7
7
 *   modify it under the terms of the GNU Lesser General Public
21
21
 */
22
22
 
23
23
#include        <freeradius-devel/ident.h>
24
 
RCSID("$Id: vqp.c,v 1.4 2008/01/05 17:58:44 nbk Exp $");
 
24
RCSID("$Id$");
25
25
 
26
26
#include        <freeradius-devel/libradius.h>
27
27
#include        <freeradius-devel/udpfromto.h>
29
29
 
30
30
#ifdef WITH_VMPS
31
31
 
 
32
#define MAX_VMPS_LEN (MAX_STRING_LEN - 1)
 
33
 
32
34
/*
33
35
 *  http://www.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/tcpdump/print-vqp.c
34
36
 *
78
80
                      int dst_port)
79
81
{
80
82
        struct sockaddr_storage dst;
81
 
        socklen_t               sizeof_dst = sizeof(dst);
 
83
        socklen_t               sizeof_dst;
82
84
 
83
85
#ifdef WITH_UDPFROMTO
84
86
        struct sockaddr_storage src;
85
 
        socklen_t               sizeof_src = sizeof(src);
86
 
 
87
 
        memset(&src, 0, sizeof(src));
88
 
#endif
89
 
        memset(&dst, 0, sizeof(dst));
90
 
 
91
 
        /*
92
 
         *      IPv4 is supported.
93
 
         */
94
 
        if (dst_ipaddr->af == AF_INET) {
95
 
                struct sockaddr_in      *s4;
96
 
 
97
 
                s4 = (struct sockaddr_in *)&dst;
98
 
                sizeof_dst = sizeof(struct sockaddr_in);
99
 
 
100
 
                s4->sin_family = AF_INET;
101
 
                s4->sin_addr = dst_ipaddr->ipaddr.ip4addr;
102
 
                s4->sin_port = htons(dst_port);
103
 
 
104
 
#ifdef WITH_UDPFROMTO
105
 
                s4 = (struct sockaddr_in *)&src;
106
 
                sizeof_src = sizeof(struct sockaddr_in);
107
 
 
108
 
                s4->sin_family = AF_INET;
109
 
                s4->sin_addr = src_ipaddr->ipaddr.ip4addr;
110
 
#endif
111
 
 
112
 
        /*
113
 
         *      IPv6 MAY be supported.
114
 
         */
115
 
#ifdef HAVE_STRUCT_SOCKADDR_IN6
116
 
        } else if (dst_ipaddr->af == AF_INET6) {
117
 
                struct sockaddr_in6     *s6;
118
 
 
119
 
                s6 = (struct sockaddr_in6 *)&dst;
120
 
                sizeof_dst = sizeof(struct sockaddr_in6);
121
 
                
122
 
                s6->sin6_family = AF_INET6;
123
 
                s6->sin6_addr = dst_ipaddr->ipaddr.ip6addr;
124
 
                s6->sin6_port = htons(dst_port);
125
 
 
126
 
#ifdef WITH_UDPFROMTO
127
 
                return -1;      /* UDPFROMTO && IPv6 are not supported */
128
 
#if 0
129
 
                s6 = (struct sockaddr_in6 *)&src;
130
 
                sizeof_src = sizeof(struct sockaddr_in6);
131
 
 
132
 
                s6->sin6_family = AF_INET6;
133
 
                s6->sin6_addr = src_ipaddr->ipaddr.ip6addr;
134
 
#endif /* #if 0 */
135
 
#endif /* WITH_UDPFROMTO */
136
 
#endif /* HAVE_STRUCT_SOCKADDR_IN6 */
137
 
        } else return -1;   /* Unknown address family, Die Die Die! */
 
87
        socklen_t               sizeof_src;
 
88
 
 
89
        fr_ipaddr2sockaddr(src_ipaddr, 0, &src, &sizeof_src);
 
90
#else
 
91
        src_ipaddr = src_ipaddr; /* -Wunused */
 
92
#endif
 
93
 
 
94
        if (!fr_ipaddr2sockaddr(dst_ipaddr, dst_port, &dst, &sizeof_dst)) {
 
95
                return -1;   /* Unknown address family, Die Die Die! */
 
96
        }
138
97
 
139
98
#ifdef WITH_UDPFROMTO
140
99
        /*
178
137
        uint8_t                 header[4];
179
138
        void                    *buf;
180
139
        size_t                  len;
 
140
        int                     port;
181
141
 
182
142
        memset(&src, 0, sizeof_src);
183
143
        memset(&dst, 0, sizeof_dst);
240
200
                        /*
241
201
                         *      Maximum length we support.
242
202
                         */
243
 
                        len = (12 * (4 + 4 + 253));
 
203
                        len = (12 * (4 + 4 + MAX_VMPS_LEN));
244
204
 
245
205
                } else {
246
206
                        if (len != 2) {
251
211
                        /*
252
212
                         *      Maximum length we support.
253
213
                         */
254
 
                        len = (12 * (4 + 4 + 253));
 
214
                        len = (12 * (4 + 4 + MAX_VMPS_LEN));
255
215
                }
256
216
#endif
257
217
        }
259
219
        /*
260
220
         *      For now, be generous.
261
221
         */
262
 
        len = (12 * (4 + 4 + 253));
 
222
        len = (12 * (4 + 4 + MAX_VMPS_LEN));
263
223
 
264
224
        buf = malloc(len);
265
225
        if (!buf) return -1;
285
245
                return data_len;
286
246
        }
287
247
 
288
 
        /*
289
 
         *      Check address families, and update src/dst ports, etc.
290
 
         */
291
 
        if (src.ss_family == AF_INET) {
292
 
                struct sockaddr_in      *s4;
293
 
 
294
 
                s4 = (struct sockaddr_in *)&src;
295
 
                src_ipaddr->af = AF_INET;
296
 
                src_ipaddr->ipaddr.ip4addr = s4->sin_addr;
297
 
                *src_port = ntohs(s4->sin_port);
298
 
 
299
 
                s4 = (struct sockaddr_in *)&dst;
300
 
                dst_ipaddr->af = AF_INET;
301
 
                dst_ipaddr->ipaddr.ip4addr = s4->sin_addr;
302
 
                *dst_port = ntohs(s4->sin_port);
303
 
 
304
 
#ifdef HAVE_STRUCT_SOCKADDR_IN6
305
 
        } else if (src.ss_family == AF_INET6) {
306
 
                struct sockaddr_in6     *s6;
307
 
 
308
 
                s6 = (struct sockaddr_in6 *)&src;
309
 
                src_ipaddr->af = AF_INET6;
310
 
                src_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
311
 
                *src_port = ntohs(s6->sin6_port);
312
 
 
313
 
                s6 = (struct sockaddr_in6 *)&dst;
314
 
                dst_ipaddr->af = AF_INET6;
315
 
                dst_ipaddr->ipaddr.ip6addr = s6->sin6_addr;
316
 
                *dst_port = ntohs(s6->sin6_port);
317
 
#endif
318
 
        } else {
 
248
        if (!fr_sockaddr2ipaddr(&src, sizeof_src, src_ipaddr, &port)) {
319
249
                free(buf);
320
250
                return -1;      /* Unknown address family, Die Die Die! */
321
251
        }
322
 
        
 
252
        *src_port = port;
 
253
 
 
254
        fr_sockaddr2ipaddr(&dst, sizeof_dst, dst_ipaddr, &port);
 
255
        *dst_port = port;
 
256
 
323
257
        /*
324
258
         *      Different address families should never happen.
325
259
         */
347
281
         *      Allocate the new request data structure
348
282
         */
349
283
        if ((packet = malloc(sizeof(*packet))) == NULL) {
350
 
                librad_log("out of memory");
 
284
                fr_strerror_printf("out of memory");
351
285
                return NULL;
352
286
        }
353
287
        memset(packet, 0, sizeof(*packet));
360
294
         *      Check for socket errors.
361
295
         */
362
296
        if (packet->data_len < 0) {
363
 
                librad_log("Error receiving packet: %s", strerror(errno));
 
297
                fr_strerror_printf("Error receiving packet: %s", strerror(errno));
364
298
                /* packet->data is NULL */
365
299
                free(packet);
366
300
                return NULL;
373
307
         *      packet than normal implementations may send.
374
308
         */
375
309
        if (packet->data_len < VQP_HDR_LEN) {
376
 
                librad_log("VQP packet is too short");
 
310
                fr_strerror_printf("VQP packet is too short");
377
311
                rad_free(&packet);
378
312
                return NULL;
379
313
        }
391
325
        }
392
326
 
393
327
        if (ptr[3] > VQP_MAX_ATTRIBUTES) {
394
 
                librad_log("Too many VQP attributes");
 
328
                fr_strerror_printf("Too many VQP attributes");
395
329
                rad_free(&packet);
396
330
                return NULL;
397
331
        }
407
341
 
408
342
                while (length > 0) {
409
343
                        if (length < 7) {
410
 
                                librad_log("Packet contains malformed attribute");
 
344
                                fr_strerror_printf("Packet contains malformed attribute");
411
345
                                rad_free(&packet);
412
346
                                return NULL;
413
347
                        }
418
352
                         */
419
353
                        if ((ptr[0] != 0) || (ptr[1] != 0) ||
420
354
                            (ptr[2] != 0x0c) || (ptr[3] < 1) || (ptr[3] > 8)) {
421
 
                                librad_log("Packet contains invalid attribute");
 
355
                                fr_strerror_printf("Packet contains invalid attribute");
422
356
                                rad_free(&packet);
423
357
                                return NULL;
424
358
                        }
425
 
                        
 
359
 
426
360
                        /*
427
361
                         *      Length is 2 bytes
428
362
                         *
430
364
                         *      server reasons.  Also, there's no reason
431
365
                         *      for bigger lengths to exist... admins
432
366
                         *      won't be typing in a 32K vlan name.
 
367
                         *
 
368
                         *      Except for received ethernet frames...
 
369
                         *      they get chopped to 253 internally.
433
370
                         */
434
 
                        if ((ptr[4] != 0) || (ptr[5] > 253)) {
435
 
                                librad_log("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
 
371
                        if ((ptr[3] != 5) &&
 
372
                            ((ptr[4] != 0) || (ptr[5] > MAX_VMPS_LEN))) {
 
373
                                fr_strerror_printf("Packet contains attribute with invalid length %02x %02x", ptr[4], ptr[5]);
436
374
                                rad_free(&packet);
437
375
                                return NULL;
438
376
                        }
499
437
 
500
438
        vp = paircreate(PW_VQP_PACKET_TYPE, PW_TYPE_OCTETS);
501
439
        if (!vp) {
502
 
                librad_log("No memory");
 
440
                fr_strerror_printf("No memory");
503
441
                return -1;
504
442
        }
505
443
        vp->lvalue = packet->data[1];
510
448
 
511
449
        vp = paircreate(PW_VQP_ERROR_CODE, PW_TYPE_OCTETS);
512
450
        if (!vp) {
513
 
                librad_log("No memory");
 
451
                fr_strerror_printf("No memory");
514
452
                return -1;
515
453
        }
516
454
        vp->lvalue = packet->data[2];
521
459
 
522
460
        vp = paircreate(PW_VQP_SEQUENCE_NUMBER, PW_TYPE_OCTETS);
523
461
        if (!vp) {
524
 
                librad_log("No memory");
 
462
                fr_strerror_printf("No memory");
525
463
                return -1;
526
464
        }
527
465
        vp->lvalue = packet->id; /* already set by vqp_recv */
540
478
         */
541
479
        while (ptr < end) {
542
480
                attribute = (ptr[2] << 8) | ptr[3];
543
 
                length = ptr[5];
 
481
                length = (ptr[4] << 8) | ptr[5];
544
482
                ptr += 6;
545
483
 
546
484
                /*
551
489
                if (!vp) {
552
490
                        pairfree(&packet->vps);
553
491
 
554
 
                        librad_log("No memory");
 
492
                        fr_strerror_printf("No memory");
555
493
                        return -1;
556
494
                }
557
495
 
566
504
                        /* FALL-THROUGH */
567
505
 
568
506
                default:
 
507
                case PW_TYPE_OCTETS:
569
508
                case PW_TYPE_STRING:
570
 
                case PW_TYPE_OCTETS:
 
509
                        vp->length = (length > MAX_VMPS_LEN) ? MAX_VMPS_LEN : length;
571
510
                        memcpy(vp->vp_octets, ptr, length);
572
 
                        vp->length = length;
 
511
                        vp->vp_octets[length] = '\0';
573
512
                        break;
574
513
                }
575
514
                ptr += length;
611
550
        VALUE_PAIR      *vps[VQP_MAX_ATTRIBUTES];
612
551
 
613
552
        if (!packet) {
614
 
                librad_log("Failed encoding VQP");
 
553
                fr_strerror_printf("Failed encoding VQP");
615
554
                return -1;
616
555
        }
617
556
 
619
558
 
620
559
        vp = pairfind(packet->vps, PW_VQP_PACKET_TYPE);
621
560
        if (!vp) {
622
 
                librad_log("Failed to find VQP-Packet-Type in response packet");
 
561
                fr_strerror_printf("Failed to find VQP-Packet-Type in response packet");
623
562
                return -1;
624
563
        }
625
564
 
626
565
        code = vp->lvalue;
627
566
        if ((code < 1) || (code > 4)) {
628
 
                librad_log("Invalid value %d for VQP-Packet-Type", code);
 
567
                fr_strerror_printf("Invalid value %d for VQP-Packet-Type", code);
629
568
                return -1;
630
569
        }
631
570
 
653
592
                 *      FIXME: Print the name...
654
593
                 */
655
594
                if (!vps[i]) {
656
 
                        librad_log("Failed to find VQP attribute %02x",
 
595
                        fr_strerror_printf("Failed to find VQP attribute %02x",
657
596
                                   contents[code][i]);
658
597
                        return -1;
659
598
                }
664
603
 
665
604
        packet->data = malloc(length);
666
605
        if (!packet->data) {
667
 
                librad_log("No memory");
 
606
                fr_strerror_printf("No memory");
668
607
                return -1;
669
608
        }
670
609
        packet->data_len = length;
693
632
                memcpy(ptr + 4, &sequence, 4);
694
633
        } else {
695
634
                if (!original) {
696
 
                        librad_log("Cannot send VQP response without request");
 
635
                        fr_strerror_printf("Cannot send VQP response without request");
697
636
                        return -1;
698
637
                }
699
638