~ubuntu-branches/ubuntu/hardy/freeradius/hardy-proposed

« back to all changes in this revision

Viewing changes to src/main/radclient.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2006-12-16 20:45:11 UTC
  • mfrom: (3.1.10 feisty)
  • Revision ID: james.westby@ubuntu.com-20061216204511-3pbbsu4s8jtehsor
Tags: 1.1.3-3
Fix POSIX compliance problem in init script.  Closes: #403384. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * radclient.c  General radius packet debug tool.
3
3
 *
4
 
 * Version:     $Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $
 
4
 * Version:     $Id: radclient.c,v 1.72.2.1.2.5 2006/05/16 18:26:08 aland Exp $
5
5
 *
6
6
 *   This program is free software; you can redistribute it and/or modify
7
7
 *   it under the terms of the GNU General Public License as published by
21
21
 * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
22
22
 * Copyright 2000  Alan DeKok <aland@ox.org>
23
23
 */
24
 
static const char rcsid[] = "$Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $";
 
24
static const char rcsid[] = "$Id: radclient.c,v 1.72.2.1.2.5 2006/05/16 18:26:08 aland Exp $";
25
25
 
26
26
#include "autoconf.h"
27
 
#include "libradius.h"
28
27
 
29
28
#include <stdio.h>
30
29
#include <stdlib.h>
55
54
#include "conf.h"
56
55
#include "radpaths.h"
57
56
#include "missing.h"
 
57
#include "libradius.h"
58
58
 
59
59
static int retries = 10;
60
60
static float timeout = 3;
98
98
static radclient_t *radclient_tail = NULL;
99
99
 
100
100
 
101
 
static void usage(void)
 
101
static void NEVER_RETURNS usage(void)
102
102
{
103
103
        fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");
104
104
 
105
 
        fprintf(stderr, "  <command>    One of auth, acct, status, or disconnect.\n");
 
105
        fprintf(stderr, "  <command>    One of auth, acct, status, coa, or disconnect.\n");
106
106
        fprintf(stderr, "  -c count    Send each packet 'count' times.\n");
107
107
        fprintf(stderr, "  -d raddb    Set dictionary directory.\n");
108
108
        fprintf(stderr, "  -f file     Read packets from file, not stdin.\n");
109
 
        fprintf(stderr, "  -r retries  If timeout, retry sending the packet 'retries' times.\n");
110
 
        fprintf(stderr, "  -t timeout  Wait 'timeout' seconds before retrying (may be a floating point number).\n");
111
109
        fprintf(stderr, "  -i id       Set request id to 'id'.  Values may be 0..255\n");
112
 
        fprintf(stderr, "  -S file     read secret from file, not command line.\n");
 
110
        fprintf(stderr, "  -n num      Send N requests/s\n");
 
111
        fprintf(stderr, "  -p num      Send 'num' packets from a file in parallel.\n");
113
112
        fprintf(stderr, "  -q          Do not print anything out.\n");
 
113
        fprintf(stderr, "  -r retries  If timeout, retry sending the packet 'retries' times.\n");
114
114
        fprintf(stderr, "  -s          Print out summary information of auth results.\n");
 
115
        fprintf(stderr, "  -S file     read secret from file, not command line.\n");
 
116
        fprintf(stderr, "  -t timeout  Wait 'timeout' seconds before retrying (may be a floating point number).\n");
115
117
        fprintf(stderr, "  -v          Show program version information.\n");
116
118
        fprintf(stderr, "  -x          Debugging mode.\n");
117
119
 
188
190
                 */
189
191
                radclient = malloc(sizeof(*radclient));
190
192
                if (!radclient) {
191
 
                        perror("radclient: ");
 
193
                        perror("radclient: X");
192
194
                        return NULL; /* memory leak "start" */
193
195
                }
194
196
                memset(radclient, 0, sizeof(*radclient));
195
197
 
196
198
                radclient->request = rad_alloc(1);
197
199
                if (!radclient->request) {
198
 
                        librad_perror("radclient: ");
 
200
                        librad_perror("radclient: X");
199
201
                        radclient_free(radclient);
200
202
                        return NULL; /* memory leak "start" */
201
203
                }
207
209
                /*
208
210
                 *      Read the VP's.
209
211
                 */
210
 
                radclient->request->vps = readvp2(fp, &filedone, "radclient:");
 
212
                radclient->request->vps = readvp2(fp, &filedone, "radclient: X");
211
213
                if (!radclient->request->vps) {
212
214
                        radclient_free(radclient);
213
215
                        return start; /* done: return the list */
217
219
                 *      Keep a copy of the the User-Password attribute.
218
220
                 */
219
221
                if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
220
 
                        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));
 
222
                        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
221
223
                        /*
222
224
                         *      Otherwise keep a copy of the CHAP-Password attribute.
223
225
                         */
224
226
                } else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
225
 
                        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));
 
227
                        strNcpy(radclient->password, (char *)vp->strvalue, sizeof(radclient->password));
226
228
                } else {
227
229
                        radclient->password[0] = '\0';
228
230
                }
319
321
        return strcmp((const char *) one, (const char *) two);
320
322
}
321
323
 
322
 
static int filename_walk(void *data)
 
324
static int filename_walk(void *context, void *data)
323
325
{
324
326
        const char      *filename = data;
325
327
        radclient_t     *radclient;
326
328
 
 
329
        context = context;      /* -Wunused */
 
330
 
327
331
        /*
328
332
         *      Initialize the request we're about
329
333
         *      to send.
477
481
                        VALUE_PAIR *vp;
478
482
 
479
483
                        if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {
480
 
                                strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
481
 
                                vp->length = strlen(radclient->password);
 
484
                                strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
 
485
                                vp->length = strlen(vp->strvalue);
482
486
 
483
487
                        } else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {
484
 
                                strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);
485
 
                                vp->length = strlen(radclient->password);
 
488
                                strNcpy((char *)vp->strvalue, radclient->password, sizeof(vp->strvalue));
 
489
                                vp->length = strlen(vp->strvalue);
486
490
 
487
491
                                rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);
488
492
                                vp->length = 17;
565
569
        /*
566
570
         *      Send the packet.
567
571
         */
568
 
        rad_send(radclient->request, NULL, secret);
 
572
        if (rad_send(radclient->request, NULL, secret) < 0) {
 
573
                fprintf(stderr, "radclient: Failed to send packet for ID %d: %s\n",
 
574
                        radclient->request->id, librad_errstr);
 
575
        }
569
576
 
570
577
        return 0;
571
578
}
617
624
        node = rbtree_find(request_tree, &myclient);
618
625
        if (!node) {
619
626
                fprintf(stderr, "radclient: received response to request we did not send.\n");
 
627
                rad_free(&reply);
620
628
                return -1;      /* got reply to packet we didn't send */
621
629
        }
622
630
 
632
640
        /*
633
641
         *      FIXME: Do stuff to process the reply.
634
642
         */
 
643
        if (rad_verify(reply, radclient->request, secret) != 0) {
 
644
                librad_perror("rad_verify");
 
645
                totallost++;
 
646
                goto packet_done; /* shared secret is incorrect */
 
647
        }
 
648
 
635
649
        if (rad_decode(reply, radclient->request, secret) != 0) {
636
650
                librad_perror("rad_decode");
637
651
                totallost++;
638
 
                return -1;
 
652
                goto packet_done; /* shared secret is incorrect */
639
653
        }
640
654
 
641
655
        /* libradius debug already prints out the value pairs for us */
650
664
                totaldeny++;
651
665
        }
652
666
 
653
 
        if (radclient->reply) rad_free(&radclient->reply);
 
667
packet_done:
 
668
        rad_free(&radclient->reply);
654
669
 
655
670
        /*
656
671
         *      Once we've sent the packet as many times as requested,
684
699
        char filesecret[256];
685
700
        FILE *fp;
686
701
        int do_summary = 0;
 
702
        int persec = 0;
 
703
        int parallel = 1;
687
704
        radclient_t     *this;
688
705
 
689
706
        librad_debug = 0;
700
717
                exit(1);
701
718
        }
702
719
 
703
 
        while ((c = getopt(argc, argv, "c:d:f:hi:qst:r:S:xv")) != EOF) switch(c) {
 
720
        while ((c = getopt(argc, argv, "c:d:f:hi:n:p:qr:sS:t:vx")) != EOF) switch(c) {
704
721
                case 'c':
705
722
                        if (!isdigit((int) *optarg))
706
723
                                usage();
712
729
                case 'f':
713
730
                        rbtree_insert(filename_tree, optarg);
714
731
                        break;
 
732
                case 'i':
 
733
                        if (!isdigit((int) *optarg))
 
734
                                usage();
 
735
                        last_used_id = atoi(optarg);
 
736
                        if ((last_used_id < 0) || (last_used_id > 255)) {
 
737
                                usage();
 
738
                        }
 
739
                        break;
 
740
 
 
741
                case 'n':
 
742
                        persec = atoi(optarg);
 
743
                        if (persec <= 0) usage();
 
744
                        break;
 
745
 
 
746
                case 'p':
 
747
                        parallel = atoi(optarg);
 
748
                        if (parallel <= 0) usage();
 
749
                        break;
 
750
 
715
751
                case 'q':
716
752
                        do_output = 0;
717
753
                        break;
718
 
                case 'x':
719
 
                        librad_debug++;
720
 
                        break;
721
754
                case 'r':
722
755
                        if (!isdigit((int) *optarg))
723
756
                                usage();
724
757
                        retries = atoi(optarg);
725
758
                        if ((retries == 0) || (retries > 1000)) usage();
726
759
                        break;
727
 
                case 'i':
728
 
                        if (!isdigit((int) *optarg))
729
 
                                usage();
730
 
                        last_used_id = atoi(optarg);
731
 
                        if ((last_used_id < 0) || (last_used_id > 255)) {
732
 
                                usage();
733
 
                        }
734
 
                        break;
735
760
                case 's':
736
761
                        do_summary = 1;
737
762
                        break;
738
 
                case 't':
739
 
                        if (!isdigit((int) *optarg))
740
 
                                usage();
741
 
                        timeout = atof(optarg);
742
 
                        break;
743
 
                case 'v':
744
 
                        printf("radclient: $Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");
745
 
                        exit(0);
746
 
                        break;
747
763
               case 'S':
748
764
                       fp = fopen(optarg, "r");
749
765
                       if (!fp) {
772
788
                       }
773
789
                       secret = filesecret;
774
790
                       break;
 
791
                case 't':
 
792
                        if (!isdigit((int) *optarg))
 
793
                                usage();
 
794
                        timeout = atof(optarg);
 
795
                        break;
 
796
                case 'v':
 
797
                        printf("radclient: $Id: radclient.c,v 1.72.2.1.2.5 2006/05/16 18:26:08 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");
 
798
                        exit(0);
 
799
                        break;
 
800
                case 'x':
 
801
                        librad_debug++;
 
802
                        break;
775
803
                case 'h':
776
804
                default:
777
805
                        usage();
815
843
                if (server_port == 0) server_port = PW_AUTH_UDP_PORT;
816
844
                packet_code = PW_AUTHENTICATION_REQUEST;
817
845
 
 
846
        } else if (strcmp(argv[2], "challenge") == 0) {
 
847
                if (server_port == 0) server_port = getport("radius");
 
848
                if (server_port == 0) server_port = PW_AUTH_UDP_PORT;
 
849
                packet_code = PW_ACCESS_CHALLENGE;
 
850
 
818
851
        } else if (strcmp(argv[2], "acct") == 0) {
819
852
                if (server_port == 0) server_port = getport("radacct");
820
853
                if (server_port == 0) server_port = PW_ACCT_UDP_PORT;
830
863
                if (server_port == 0) server_port = PW_POD_UDP_PORT;
831
864
                packet_code = PW_DISCONNECT_REQUEST;
832
865
 
 
866
        } else if (strcmp(argv[2], "coa") == 0) {
 
867
                if (server_port == 0) server_port = PW_POD_UDP_PORT;
 
868
                packet_code = PW_COA_REQUEST;
 
869
 
833
870
        } else if (strcmp(argv[2], "auto") == 0) {
834
871
                packet_code = -1;
835
872
 
865
902
        /*
866
903
         *      Walk over the list of filenames, creating the requests.
867
904
         */
868
 
        if (rbtree_walk(filename_tree, filename_walk, InOrder) != 0) {
 
905
        if (rbtree_walk(filename_tree, InOrder, filename_walk, NULL) != 0) {
869
906
                exit(1);
870
907
        }
871
908
 
899
936
         *      loop.
900
937
         */
901
938
        do {
 
939
                int n = parallel;
902
940
                radclient_t *next;
903
941
                const char *filename = NULL;
904
942
 
929
967
 
930
968
                        /*
931
969
                         *      Packets from multiple '-f' are sent
932
 
                         *      in parallel.  Packets from one file
933
 
                         *      are sent in series.
 
970
                         *      in parallel.
 
971
                         *
 
972
                         *      Packets from one file are sent in
 
973
                         *      series, unless '-p' is specified, in
 
974
                         *      which case N packets from each file
 
975
                         *      are sent in parallel.
934
976
                         */
935
977
                        if (this->filename != filename) {
936
978
                                filename = this->filename;
 
979
                                n = parallel;
 
980
                        }
 
981
 
 
982
                        if (n > 0) {
 
983
                                n--;
937
984
 
938
985
                                /*
939
986
                                 *      Send the current packet.
941
988
                                send_one_packet(this);
942
989
 
943
990
                                /*
 
991
                                 *      Wait a little before sending
 
992
                                 *      the next packet, if told to.
 
993
                                 */
 
994
                                if (persec) {
 
995
                                        struct timeval tv;
 
996
 
 
997
                                        /*
 
998
                                         *      Don't sleep elsewhere.
 
999
                                         */
 
1000
                                        sleep_time = 0;
 
1001
 
 
1002
                                        if (persec == 1) {
 
1003
                                                tv.tv_sec = 1;
 
1004
                                                tv.tv_usec = 0;
 
1005
                                        } else {
 
1006
                                                tv.tv_sec = 0;
 
1007
                                                tv.tv_usec = 1000000/persec;
 
1008
                                        }
 
1009
                                        
 
1010
                                        /*
 
1011
                                         *      Sleep for milliseconds,
 
1012
                                         *      portably.
 
1013
                                         *
 
1014
                                         *      If we get an error or
 
1015
                                         *      a signal, treat it like
 
1016
                                         *      a normal timeout.
 
1017
                                         */
 
1018
                                        select(0, NULL, NULL, NULL, &tv);
 
1019
                                }
 
1020
 
 
1021
                                /*
944
1022
                                 *      If we haven't sent this packet
945
1023
                                 *      often enough, we're not done,
946
1024
                                 *      and we shouldn't sleep.