dfb61bbacd07cc36a83a9db1ed6396de0b671cc2
[freeradius.git] / src / main / radclient.c
1 /*
2  * radclient.c  General radius packet debug tool.
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2000,2006,2014  The FreeRADIUS server project
21  * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl>
22  * Copyright 2000  Alan DeKok <aland@ox.org>
23  */
24
25 RCSID("$Id$")
26
27 #include <freeradius-devel/radclient.h>
28 #include <freeradius-devel/radpaths.h>
29 #include <freeradius-devel/conf.h>
30 #include <ctype.h>
31
32 #ifdef HAVE_GETOPT_H
33 #  include <getopt.h>
34 #endif
35
36 #include <assert.h>
37
38 typedef struct REQUEST REQUEST; /* to shut up warnings about mschap.h */
39
40 #include "smbdes.h"
41 #include "mschap.h"
42
43 static int retries = 3;
44 static float timeout = 5;
45 static char const *secret = NULL;
46 static bool do_output = true;
47
48 static rc_stats_t stats;
49
50 static uint16_t server_port = 0;
51 static int packet_code = 0;
52 static fr_ipaddr_t server_ipaddr;
53 static int resend_count = 1;
54 static bool done = true;
55 static bool print_filename = false;
56
57 static fr_ipaddr_t client_ipaddr;
58 static uint16_t client_port = 0;
59
60 static int sockfd;
61 static int last_used_id = -1;
62
63 #ifdef WITH_TCP
64 char const *proto = NULL;
65 #endif
66 static int ipproto = IPPROTO_UDP;
67
68 static rbtree_t *filename_tree = NULL;
69 static fr_packet_list_t *pl = NULL;
70
71 static int sleep_time = -1;
72
73 static rc_request_t *request_head = NULL;
74 static rc_request_t *rc_request_tail = NULL;
75
76 static int rc_debug_flag;
77
78 char const *radclient_version = "radclient version " RADIUSD_VERSION_STRING
79 #ifdef RADIUSD_VERSION_COMMIT
80 " (git #" STRINGIFY(RADIUSD_VERSION_COMMIT) ")"
81 #endif
82 ", built on " __DATE__ " at " __TIME__;
83
84 static void NEVER_RETURNS usage(void)
85 {
86         fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");
87
88         fprintf(stderr, "  <command>              One of auth, acct, status, coa, or disconnect.\n");
89         fprintf(stderr, "  -4                     Use IPv4 address of server\n");
90         fprintf(stderr, "  -6                     Use IPv6 address of server.\n");
91         fprintf(stderr, "  -c <count>             Send each packet 'count' times.\n");
92         fprintf(stderr, "  -d <raddb>             Set user dictionary directory (defaults to " RADDBDIR ").\n");
93         fprintf(stderr, "  -D <dictdir>           Set main dictionary directory (defaults to " DICTDIR ").\n");
94         fprintf(stderr, "  -f <file>[:<file>]     Read packets from file, not stdin.\n");
95         fprintf(stderr, "                         If a second file is provided, it will be used to verify responses\n");
96         fprintf(stderr, "  -F                     Print the file name, packet number and reply code.\n");
97         fprintf(stderr, "  -h                     Print usage help information.\n");
98         fprintf(stderr, "  -i <id>                Set request id to 'id'.  Values may be 0..255\n");
99         fprintf(stderr, "  -n <num>               Send N requests/s\n");
100         fprintf(stderr, "  -p <num>               Send 'num' packets from a file in parallel.\n");
101         fprintf(stderr, "  -q                     Do not print anything out.\n");
102         fprintf(stderr, "  -r <retries>           If timeout, retry sending the packet 'retries' times.\n");
103         fprintf(stderr, "  -s                     Print out summary information of auth results.\n");
104         fprintf(stderr, "  -S <file>              read secret from file, not command line.\n");
105         fprintf(stderr, "  -t <timeout>           Wait 'timeout' seconds before retrying (may be a floating point number).\n");
106         fprintf(stderr, "  -v                     Show program version information.\n");
107         fprintf(stderr, "  -x                     Debugging mode.\n");
108
109 #ifdef WITH_TCP
110         fprintf(stderr, "  -P <proto>             Use proto (tcp or udp) for transport.\n");
111 #endif
112
113         exit(1);
114 }
115
116 static const FR_NAME_NUMBER request_types[] = {
117         { "auth",       PW_CODE_AUTHENTICATION_REQUEST },
118         { "challenge",  PW_CODE_ACCESS_CHALLENGE },
119         { "acct",       PW_CODE_ACCOUNTING_REQUEST },
120         { "status",     PW_CODE_STATUS_SERVER },
121         { "disconnect", PW_CODE_DISCONNECT_REQUEST },
122         { "coa",        PW_CODE_COA_REQUEST },
123         { "auto",       PW_CODE_UNDEFINED },
124
125         { NULL, 0}
126 };
127
128 /*
129  *      Free a radclient struct, which may (or may not)
130  *      already be in the list.
131  */
132 static int _rc_request_free(rc_request_t *request)
133 {
134         rc_request_t *prev, *next;
135
136         prev = request->prev;
137         next = request->next;
138
139         if (prev) {
140                 assert(request_head != request);
141                 prev->next = next;
142         } else if (request_head) {
143                 assert(request_head == request);
144                 request_head = next;
145         }
146
147         if (next) {
148                 assert(rc_request_tail != request);
149                 next->prev = prev;
150         } else if (rc_request_tail) {
151                 assert(rc_request_tail == request);
152                 rc_request_tail = prev;
153         }
154
155         return 0;
156 }
157
158 static int mschapv1_encode(RADIUS_PACKET *packet, VALUE_PAIR **request,
159                            char const *password)
160 {
161         unsigned int i;
162         uint8_t *p;
163         VALUE_PAIR *challenge, *reply;
164         uint8_t nthash[16];
165
166         challenge = paircreate(packet, PW_MSCHAP_CHALLENGE, VENDORPEC_MICROSOFT);
167         if (!challenge) {
168                 return 0;
169         }
170
171         pairadd(request, challenge);
172         challenge->length = 8;
173         challenge->vp_octets = p = talloc_array(challenge, uint8_t, challenge->length);
174         for (i = 0; i < challenge->length; i++) {
175                 p[i] = fr_rand();
176         }
177
178         reply = paircreate(packet, PW_MSCHAP_RESPONSE, VENDORPEC_MICROSOFT);
179         if (!reply) {
180                 return 0;
181         }
182
183         pairadd(request, reply);
184         reply->length = 50;
185         reply->vp_octets = p = talloc_array(reply, uint8_t, reply->length);
186         memset(p, 0, reply->length);
187
188         p[1] = 0x01; /* NT hash */
189
190         if (mschap_ntpwdhash(nthash, password) < 0) {
191                 return 0;
192         }
193
194         smbdes_mschap(nthash, challenge->vp_octets, p + 26);
195         return 1;
196 }
197
198
199 static int getport(char const *name)
200 {
201         struct  servent *svp;
202
203         svp = getservbyname(name, "udp");
204         if (!svp) {
205                 return 0;
206         }
207
208         return ntohs(svp->s_port);
209 }
210
211 static void radclient_get_port(PW_CODE type, uint16_t *port)
212 {
213         switch (type) {
214         default:
215         case PW_CODE_AUTHENTICATION_REQUEST:
216         case PW_CODE_ACCESS_CHALLENGE:
217         case PW_CODE_STATUS_SERVER:
218                 if (*port == 0) *port = getport("radius");
219                 if (*port == 0) *port = PW_AUTH_UDP_PORT;
220                 return;
221
222         case PW_CODE_ACCOUNTING_REQUEST:
223                 if (*port == 0) *port = getport("radacct");
224                 if (*port == 0) *port = PW_ACCT_UDP_PORT;
225                 return;
226
227         case PW_CODE_DISCONNECT_REQUEST:
228         case PW_CODE_COA_REQUEST:
229                 if (*port == 0) *port = PW_COA_UDP_PORT;
230                 return;
231
232         case PW_CODE_UNDEFINED:
233                 if (*port == 0) *port = 0;
234         }
235 }
236
237 /*
238  *      Initialize a radclient data structure and add it to
239  *      the global linked list.
240  */
241 static int radclient_init(TALLOC_CTX *ctx, rc_file_pair_t *files)
242 {
243         FILE *packets, *filters = NULL;
244
245         vp_cursor_t cursor;
246         VALUE_PAIR *vp;
247         rc_request_t *request;
248         bool packets_done = false;
249         uint64_t num = 0;
250
251         assert(files->packets != NULL);
252
253         /*
254          *      Determine where to read the VP's from.
255          */
256         if (strcmp(files->packets, "stdin") != 0) {
257                 packets = fopen(files->packets, "r");
258                 if (!packets) {
259                         ERROR("Error opening %s: %s", files->packets, strerror(errno));
260                         return 0;
261                 }
262
263                 /*
264                  *      Read in the pairs representing the expected response.
265                  */
266                 if (files->filters) {
267                         filters = fopen(files->filters, "r");
268                         if (!filters) {
269                                 ERROR("Error opening %s: %s", files->filters, strerror(errno));
270                                 fclose(packets);
271                                 return 0;
272                         }
273                 }
274         } else {
275                 packets = stdin;
276         }
277
278
279         /*
280          *      Loop until the file is done.
281          */
282         do {
283                 /*
284                  *      Allocate it.
285                  */
286                 request = talloc_zero(ctx, rc_request_t);
287                 if (!request) {
288                         ERROR("Out of memory");
289                         goto error;
290                 }
291
292                 request->packet = rad_alloc(request, 1);
293                 if (!request->packet) {
294                         ERROR("Out of memory");
295                         goto error;
296                 }
297
298 #ifdef WITH_TCP
299                 request->packet->src_ipaddr = client_ipaddr;
300                 request->packet->src_port = client_port;
301                 request->packet->dst_ipaddr = server_ipaddr;
302                 request->packet->dst_port = server_port;
303                 request->packet->proto = ipproto;
304 #endif
305
306                 request->files = files;
307                 request->packet->id = -1; /* allocate when sending */
308                 request->num = num++;
309
310                 /*
311                  *      Read the request VP's.
312                  */
313                 if (readvp2(&request->packet->vps, request->packet, packets, &packets_done) < 0) {
314                         REDEBUG("Error parsing \"%s\"", files->packets);
315                         goto error;
316                 }
317
318                 /*
319                  *      Skip empty entries
320                  */
321                 if (!request->packet->vps) {
322                         talloc_free(request);
323                         continue;
324                 }
325
326                 /*
327                  *      Read in filter VP's.
328                  */
329                 if (filters) {
330                         bool filters_done;
331
332                         if (readvp2(&request->filter, request, filters, &filters_done) < 0) {
333                                 REDEBUG("Error parsing \"%s\"", files->filters);
334                                 goto error;
335                         }
336
337                         if (filters_done && !packets_done) {
338                                 REDEBUG("Differing number of packets/filters in %s:%s "
339                                         "(too many requests))", files->packets, files->filters);
340                                 goto error;
341                         }
342
343                         if (!filters_done && packets_done) {
344                                 REDEBUG("Differing number of packets/filters in %s:%s "
345                                         "(too many filters))", files->packets, files->filters);
346                                 goto error;
347                         }
348
349                         /*
350                          *      xlat expansions aren't supported here
351                          */
352                         for (vp = fr_cursor_init(&cursor, &request->filter);
353                              vp;
354                              vp = fr_cursor_next(&cursor)) {
355                                 if (vp->type == VT_XLAT) {
356                                         vp->type = VT_DATA;
357                                         vp->vp_strvalue = vp->value.xlat;
358                                         vp->length = talloc_array_length(vp->vp_strvalue) - 1;
359                                 }
360
361                                 if (vp->da->vendor == 0 ) switch (vp->da->attr) {
362                                 case PW_RESPONSE_PACKET_TYPE:
363                                 case PW_PACKET_TYPE:
364                                         fr_cursor_remove(&cursor);      /* so we don't break the filter */
365                                         request->filter_code = vp->vp_integer;
366                                         talloc_free(vp);
367
368                                 default:
369                                         break;
370                                 }
371                         }
372
373                         /*
374                          *      This allows efficient list comparisons later
375                          */
376                         pairsort(&request->filter, attrtagcmp);
377                 }
378
379                 request->password[0] = '\0';
380                 /*
381                  *      Process special attributes
382                  */
383                 for (vp = fr_cursor_init(&cursor, &request->packet->vps);
384                      vp;
385                      vp = fr_cursor_next(&cursor)) {
386                         /*
387                          *      Double quoted strings get marked up as xlat expansions,
388                          *      but we don't support that in request.
389                          */
390                         if (vp->type == VT_XLAT) {
391                                 vp->type = VT_DATA;
392                                 vp->vp_strvalue = vp->value.xlat;
393                                 vp->length = talloc_array_length(vp->vp_strvalue) - 1;
394                         }
395
396                         if (!vp->da->vendor) switch (vp->da->attr) {
397                         default:
398                                 break;
399
400                         /*
401                          *      Allow it to set the packet type in
402                          *      the attributes read from the file.
403                          */
404                         case PW_PACKET_TYPE:
405                                 request->packet->code = vp->vp_integer;
406                                 break;
407
408                         case PW_PACKET_DST_PORT:
409                                 request->packet->dst_port = (vp->vp_integer & 0xffff);
410                                 break;
411
412                         case PW_PACKET_DST_IP_ADDRESS:
413                                 request->packet->dst_ipaddr.af = AF_INET;
414                                 request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
415                                 break;
416
417                         case PW_PACKET_DST_IPV6_ADDRESS:
418                                 request->packet->dst_ipaddr.af = AF_INET6;
419                                 request->packet->dst_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
420                                 break;
421
422                         case PW_PACKET_SRC_PORT:
423                                 request->packet->src_port = (vp->vp_integer & 0xffff);
424                                 break;
425
426                         case PW_PACKET_SRC_IP_ADDRESS:
427                                 request->packet->src_ipaddr.af = AF_INET;
428                                 request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
429                                 break;
430
431                         case PW_PACKET_SRC_IPV6_ADDRESS:
432                                 request->packet->src_ipaddr.af = AF_INET6;
433                                 request->packet->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
434                                 break;
435
436                         case PW_DIGEST_REALM:
437                         case PW_DIGEST_NONCE:
438                         case PW_DIGEST_METHOD:
439                         case PW_DIGEST_URI:
440                         case PW_DIGEST_QOP:
441                         case PW_DIGEST_ALGORITHM:
442                         case PW_DIGEST_BODY_DIGEST:
443                         case PW_DIGEST_CNONCE:
444                         case PW_DIGEST_NONCE_COUNT:
445                         case PW_DIGEST_USER_NAME:
446                         /* overlapping! */
447                         {
448                                 DICT_ATTR const *da;
449                                 uint8_t *p, *q;
450
451                                 p = talloc_array(vp, uint8_t, vp->length + 2);
452
453                                 memcpy(p + 2, vp->vp_octets, vp->length);
454                                 p[0] = vp->da->attr - PW_DIGEST_REALM + 1;
455                                 vp->length += 2;
456                                 p[1] = vp->length;
457
458                                 da = dict_attrbyvalue(PW_DIGEST_ATTRIBUTES, 0);
459                                 if (!da) {
460                                         ERROR("Out of memory");
461                                         goto error;
462                                 }
463                                 vp->da = da;
464
465                                 /*
466                                  *      Re-do pairmemsteal ourselves,
467                                  *      because we play games with
468                                  *      vp->da, and pairmemsteal goes
469                                  *      to GREAT lengths to sanitize
470                                  *      and fix and change and
471                                  *      double-check the various
472                                  *      fields.
473                                  */
474                                 memcpy(&q, &vp->vp_octets, sizeof(q));
475                                 talloc_free(q);
476
477                                 vp->vp_octets = talloc_steal(vp, p);
478                                 vp->type = VT_DATA;
479
480                                 VERIFY_VP(vp);
481                         }
482                                 break;
483
484                         /*
485                          *      Keep a copy of the the password attribute.
486                          */
487                         case PW_USER_PASSWORD:
488                         case PW_CHAP_PASSWORD:
489                         case PW_MS_CHAP_PASSWORD:
490                                 strlcpy(request->password, vp->vp_strvalue, sizeof(request->password));
491                                 break;
492
493                         case PW_RADCLIENT_TEST_NAME:
494                                 request->name = vp->vp_strvalue;
495                                 break;
496                         }
497                 } /* loop over the VP's we read in */
498
499                  /*
500                   *     Use the default set on the command line
501                   */
502                 if (request->packet->code == 0) {
503                         request->packet->code = packet_code;
504                 }
505
506                 /*
507                  *      Default to the filename
508                  */
509                 if (!request->name) {
510                         request->name = request->files->packets;
511                 }
512
513                 /*
514                  *      Automatically set the response code from the request code
515                  *      (if one wasn't already set).
516                  */
517                 if (!request->filter_code) {
518                         switch (request->packet->code) {
519                         case PW_CODE_AUTHENTICATION_REQUEST:
520                                 request->filter_code = PW_CODE_AUTHENTICATION_ACK;
521                                 break;
522
523                         case PW_CODE_ACCOUNTING_REQUEST:
524                                 request->filter_code = PW_CODE_ACCOUNTING_RESPONSE;
525                                 break;
526
527                         case PW_CODE_COA_REQUEST:
528                                 request->filter_code = PW_CODE_COA_ACK;
529                                 break;
530
531                         case PW_CODE_DISCONNECT_REQUEST:
532                                 request->filter_code = PW_CODE_DISCONNECT_ACK;
533                                 break;
534
535                         default:
536                                 break;
537                         }
538                 }
539
540                 /*
541                  *      Automatically set the dst port if one wasn't already set.
542                  */
543                 if (request->packet->dst_port == 0) {
544                         radclient_get_port(request->packet->code, &request->packet->dst_port);
545                 }
546
547                 /*
548                  *      Add it to the tail of the list.
549                  */
550                 if (!request_head) {
551                         assert(rc_request_tail == NULL);
552                         request_head = request;
553                         request->prev = NULL;
554                 } else {
555                         assert(rc_request_tail->next == NULL);
556                         rc_request_tail->next = request;
557                         request->prev = rc_request_tail;
558                 }
559                 rc_request_tail = request;
560                 request->next = NULL;
561
562                 /*
563                  *      Set the destructor so it removes itself from the
564                  *      request list when freed. We don't set this until
565                  *      the packet is actually in the list, else we trigger
566                  *      the asserts in the free callback.
567                  */
568                 talloc_set_destructor(request, _rc_request_free);
569         } while (!packets_done); /* loop until the file is done. */
570
571         if (packets != stdin) fclose(packets);
572         if (filters) fclose(filters);
573
574         /*
575          *      And we're done.
576          */
577         return 1;
578
579 error:
580         talloc_free(request);
581
582         if (packets != stdin) fclose(packets);
583         if (filters) fclose(filters);
584
585         return 0;
586 }
587
588
589 /*
590  *      Sanity check each argument.
591  */
592 static int radclient_sane(rc_request_t *request)
593 {
594         if (request->packet->dst_port == 0) {
595                 request->packet->dst_port = server_port;
596         }
597         if (request->packet->dst_ipaddr.af == AF_UNSPEC) {
598                 if (server_ipaddr.af == AF_UNSPEC) {
599                         ERROR("No server was given, and request %" PRIu64 " in file %s did not contain "
600                               "Packet-Dst-IP-Address", request->num, request->files->packets);
601                         return -1;
602                 }
603                 request->packet->dst_ipaddr = server_ipaddr;
604         }
605         if (request->packet->code == 0) {
606                 if (packet_code == -1) {
607                         ERROR("Request was \"auto\", and request %" PRIu64 " in file %s did not contain Packet-Type",
608                               request->num, request->files->packets);
609                         return -1;
610                 }
611                 request->packet->code = packet_code;
612         }
613         request->packet->sockfd = -1;
614
615         return 0;
616 }
617
618
619 /*
620  *      For request handling.
621  */
622 static int filename_cmp(void const *one, void const *two)
623 {
624         int cmp;
625
626         rc_file_pair_t const *a = one;
627         rc_file_pair_t const *b = two;
628
629         cmp = strcmp(a->packets, b->packets);
630         if (cmp != 0) return cmp;
631
632         return strcmp(a->filters, b->filters);
633 }
634
635 static int filename_walk(UNUSED void *context, void *data)
636 {
637         rc_file_pair_t *files = data;
638
639         /*
640          *      Read request(s) from the file.
641          */
642         if (!radclient_init(files, files)) {
643                 return -1;      /* stop walking */
644         }
645
646         return 0;
647 }
648
649
650 /*
651  *      Deallocate packet ID, etc.
652  */
653 static void deallocate_id(rc_request_t *request)
654 {
655         if (!request || !request->packet ||
656             (request->packet->id < 0)) {
657                 return;
658         }
659
660         /*
661          *      One more unused RADIUS ID.
662          */
663         fr_packet_list_id_free(pl, request->packet, true);
664
665         /*
666          *      If we've already sent a packet, free up the old one,
667          *      and ensure that the next packet has a unique
668          *      authentication vector.
669          */
670         if (request->packet->data) {
671                 TALLOC_FREE(request->packet->data);
672         }
673
674         if (request->reply) rad_free(&request->reply);
675 }
676
677 /*
678  *      Send one packet.
679  */
680 static int send_one_packet(rc_request_t *request)
681 {
682         assert(request->done == false);
683
684         /*
685          *      Remember when we have to wake up, to re-send the
686          *      request, of we didn't receive a reply.
687          */
688         if ((sleep_time == -1) || (sleep_time > (int) timeout)) {
689                 sleep_time = (int) timeout;
690         }
691
692         /*
693          *      Haven't sent the packet yet.  Initialize it.
694          */
695         if (request->packet->id == -1) {
696                 int i;
697                 bool rcode;
698
699                 assert(request->reply == NULL);
700
701                 /*
702                  *      Didn't find a free packet ID, we're not done,
703                  *      we don't sleep, and we stop trying to process
704                  *      this packet.
705                  */
706         retry:
707                 request->packet->src_ipaddr.af = server_ipaddr.af;
708                 rcode = fr_packet_list_id_alloc(pl, ipproto,
709                                                 &request->packet, NULL);
710                 if (!rcode) {
711                         int mysockfd;
712
713 #ifdef WITH_TCP
714                         if (proto) {
715                                 mysockfd = fr_tcp_client_socket(NULL,
716                                                                 &request->packet->dst_ipaddr,
717                                                                 request->packet->dst_port);
718                         } else
719 #endif
720                         mysockfd = fr_socket(&client_ipaddr, 0);
721                         if (mysockfd < 0) {
722                                 ERROR("Failed opening socket");
723                                 exit(1);
724                         }
725                         if (!fr_packet_list_socket_add(pl, mysockfd, ipproto,
726                                                        &request->packet->dst_ipaddr,
727                                                        request->packet->dst_port, NULL)) {
728                                 ERROR("Can't add new socket");
729                                 exit(1);
730                         }
731                         goto retry;
732                 }
733
734                 assert(request->packet->id != -1);
735                 assert(request->packet->data == NULL);
736
737                 for (i = 0; i < 4; i++) {
738                         ((uint32_t *) request->packet->vector)[i] = fr_rand();
739                 }
740
741                 /*
742                  *      Update the password, so it can be encrypted with the
743                  *      new authentication vector.
744                  */
745                 if (request->password[0] != '\0') {
746                         VALUE_PAIR *vp;
747
748                         if ((vp = pairfind(request->packet->vps, PW_USER_PASSWORD, 0, TAG_ANY)) != NULL) {
749                                 pairstrcpy(vp, request->password);
750
751                         } else if ((vp = pairfind(request->packet->vps, PW_CHAP_PASSWORD, 0, TAG_ANY)) != NULL) {
752                                 bool already_hex = false;
753
754                                 /*
755                                  *      If it's 17 octets, it *might* be already encoded.
756                                  *      Or, it might just be a 17-character password (maybe UTF-8)
757                                  *      Check it for non-printable characters.  The odds of ALL
758                                  *      of the characters being 32..255 is (1-7/8)^17, or (1/8)^17,
759                                  *      or 1/(2^51), which is pretty much zero.
760                                  */
761                                 if (vp->length == 17) {
762                                         for (i = 0; i < 17; i++) {
763                                                 if (vp->vp_octets[i] < 32) {
764                                                         already_hex = true;
765                                                         break;
766                                                 }
767                                         }
768                                 }
769
770                                 /*
771                                  *      Allow the user to specify ASCII or hex CHAP-Password
772                                  */
773                                 if (!already_hex) {
774                                         uint8_t *p;
775                                         size_t len, len2;
776
777                                         len = len2 = strlen(request->password);
778                                         if (len2 < 17) len2 = 17;
779
780                                         p = talloc_zero_array(vp, uint8_t, len2);
781
782                                         memcpy(p, request->password, len);
783
784                                         rad_chap_encode(request->packet,
785                                                         p,
786                                                         fr_rand() & 0xff, vp);
787                                         vp->vp_octets = p;
788                                         vp->length = 17;
789                                 }
790                         } else if (pairfind(request->packet->vps, PW_MS_CHAP_PASSWORD, 0, TAG_ANY) != NULL) {
791                                 mschapv1_encode(request->packet,
792                                                 &request->packet->vps,
793                                                 request->password);
794                         } else {
795                                 DEBUG("WARNING: No password in the request");
796                         }
797                 }
798
799                 request->timestamp = time(NULL);
800                 request->tries = 1;
801                 request->resend++;
802
803 #ifdef WITH_TCP
804                 /*
805                  *      WTF?
806                  */
807                 if (client_port == 0) {
808                         client_ipaddr = request->packet->src_ipaddr;
809                         client_port = request->packet->src_port;
810                 }
811 #endif
812
813         } else {                /* request->packet->id >= 0 */
814                 time_t now = time(NULL);
815
816                 /*
817                  *      FIXME: Accounting packets are never retried!
818                  *      The Acct-Delay-Time attribute is updated to
819                  *      reflect the delay, and the packet is re-sent
820                  *      from scratch!
821                  */
822
823                 /*
824                  *      Not time for a retry, do so.
825                  */
826                 if ((now - request->timestamp) < timeout) {
827                         /*
828                          *      When we walk over the tree sending
829                          *      packets, we update the minimum time
830                          *      required to sleep.
831                          */
832                         if ((sleep_time == -1) ||
833                             (sleep_time > (now - request->timestamp))) {
834                                 sleep_time = now - request->timestamp;
835                         }
836                         return 0;
837                 }
838
839                 /*
840                  *      We're not trying later, maybe the packet is done.
841                  */
842                 if (request->tries == retries) {
843                         assert(request->packet->id >= 0);
844
845                         /*
846                          *      Delete the request from the tree of
847                          *      outstanding requests.
848                          */
849                         fr_packet_list_yank(pl, request->packet);
850
851                         REDEBUG("No reply from server for ID %d socket %d",
852                                 request->packet->id, request->packet->sockfd);
853                         deallocate_id(request);
854
855                         /*
856                          *      Normally we mark it "done" when we've received
857                          *      the reply, but this is a special case.
858                          */
859                         if (request->resend == resend_count) {
860                                 request->done = true;
861                         }
862                         stats.lost++;
863                         return -1;
864                 }
865
866                 /*
867                  *      We are trying later.
868                  */
869                 request->timestamp = now;
870                 request->tries++;
871         }
872
873         /*
874          *      Send the packet.
875          */
876         if (rad_send(request->packet, NULL, secret) < 0) {
877                 REDEBUG("Failed to send packet for ID %d", request->packet->id);
878         }
879
880         return 0;
881 }
882
883 /*
884  *      Receive one packet, maybe.
885  */
886 static int recv_one_packet(int wait_time)
887 {
888         fd_set          set;
889         struct timeval  tv;
890         rc_request_t    *request;
891         RADIUS_PACKET   *reply, **packet_p;
892         volatile int max_fd;
893
894         /* And wait for reply, timing out as necessary */
895         FD_ZERO(&set);
896
897         max_fd = fr_packet_list_fd_set(pl, &set);
898         if (max_fd < 0) exit(1); /* no sockets to listen on! */
899
900         if (wait_time <= 0) {
901                 tv.tv_sec = 0;
902         } else {
903                 tv.tv_sec = wait_time;
904         }
905         tv.tv_usec = 0;
906
907         /*
908          *      No packet was received.
909          */
910         if (select(max_fd, &set, NULL, NULL, &tv) <= 0) {
911                 return 0;
912         }
913
914         /*
915          *      Look for the packet.
916          */
917         reply = fr_packet_list_recv(pl, &set);
918         if (!reply) {
919                 ERROR("Received bad packet");
920 #ifdef WITH_TCP
921                 /*
922                  *      If the packet is bad, we close the socket.
923                  *      I'm not sure how to do that now, so we just
924                  *      die...
925                  */
926                 if (proto) exit(1);
927 #endif
928                 return -1;      /* bad packet */
929         }
930
931         /*
932          *      udpfromto issues.  We may have bound to "*",
933          *      and we want to find the replies that are sent to
934          *      (say) 127.0.0.1.
935          *
936          *      This only works if were not using any of the
937          *      Packet-* attributes, or running with 'auto'.
938          */
939         reply->dst_ipaddr = client_ipaddr;
940         reply->dst_port = client_port;
941 #ifdef WITH_TCP
942         if (server_port > 0) {
943                 reply->src_ipaddr = server_ipaddr;
944                 reply->src_port = server_port;
945         }
946 #endif
947
948         packet_p = fr_packet_list_find_byreply(pl, reply);
949         if (!packet_p) {
950                 ERROR("Received reply to request we did not send. (id=%d socket %d)",
951                       reply->id, reply->sockfd);
952                 rad_free(&reply);
953                 return -1;      /* got reply to packet we didn't send */
954         }
955         request = fr_packet2myptr(rc_request_t, packet, packet_p);
956
957         /*
958          *      Fails the signature validation: not a real reply.
959          *      FIXME: Silently drop it and listen for another packet.
960          */
961         if (rad_verify(reply, request->packet, secret) < 0) {
962                 REDEBUG("Reply verification failed");
963                 stats.lost++;
964                 goto packet_done; /* shared secret is incorrect */
965         }
966
967         if (print_filename) {
968                 RDEBUG("%s response code %d", request->files->packets, reply->code);
969         }
970
971         deallocate_id(request);
972         request->reply = reply;
973         reply = NULL;
974
975         /*
976          *      If this fails, we're out of memory.
977          */
978         if (rad_decode(request->reply, request->packet, secret) != 0) {
979                 REDEBUG("Reply decode failed");
980                 stats.lost++;
981                 goto packet_done;
982         }
983
984         /*
985          *      Increment counters...
986          */
987         switch (request->reply->code) {
988         case PW_CODE_AUTHENTICATION_ACK:
989         case PW_CODE_ACCOUNTING_RESPONSE:
990         case PW_CODE_COA_ACK:
991         case PW_CODE_DISCONNECT_ACK:
992                 stats.accepted++;
993                 break;
994
995         case PW_CODE_ACCESS_CHALLENGE:
996                 break;
997
998         default:
999                 stats.rejected++;
1000         }
1001
1002         /*
1003          *      If we had an expected response code, check to see if the
1004          *      packet matched that.
1005          */
1006         if (request->reply->code != request->filter_code) {
1007                 if (is_radius_code(request->reply->code)) {
1008                         REDEBUG("%s: Expected %s got %s", request->name, fr_packet_codes[request->filter_code],
1009                                 fr_packet_codes[request->reply->code]);
1010                 } else {
1011                         REDEBUG("%s: Expected %u got %i", request->name, request->filter_code,
1012                                 request->reply->code);
1013                 }
1014                 stats.failed++;
1015         /*
1016          *      Check if the contents of the packet matched the filter
1017          */
1018         } else if (!request->filter) {
1019                 stats.passed++;
1020         } else {
1021                 VALUE_PAIR const *failed[2];
1022
1023                 pairsort(&request->reply->vps, attrtagcmp);
1024                 if (pairvalidate(failed, request->filter, request->reply->vps)) {
1025                         RDEBUG("%s: Response passed filter", request->name);
1026                         stats.passed++;
1027                 } else {
1028                         pairvalidate_debug(request, failed);
1029                         REDEBUG("%s: Response for failed filter", request->name);
1030                         stats.failed++;
1031                 }
1032         }
1033
1034         if (request->resend == resend_count) {
1035                 request->done = true;
1036         }
1037
1038 packet_done:
1039         rad_free(&request->reply);
1040         rad_free(&reply);       /* may be NULL */
1041
1042         return 0;
1043 }
1044
1045 int main(int argc, char **argv)
1046 {
1047         int c;
1048         char const *radius_dir = RADDBDIR;
1049         char const *dict_dir = DICTDIR;
1050         char filesecret[256];
1051         FILE *fp;
1052         int do_summary = false;
1053         int persec = 0;
1054         int parallel = 1;
1055         rc_request_t    *this;
1056         int force_af = AF_UNSPEC;
1057
1058         /*
1059          *      It's easier having two sets of flags to set the
1060          *      verbosity of library calls and the verbosity of
1061          *      radclient.
1062          */
1063         rc_debug_flag = 1;
1064         fr_debug_flag = 0;
1065         fr_log_fp = stdout;
1066
1067 #ifndef NDEBUG
1068         if (fr_fault_setup(getenv("PANIC_ACTION"), argv[0]) < 0) {
1069                 fr_perror("radclient");
1070                 exit(EXIT_FAILURE);
1071         }
1072 #endif
1073
1074         talloc_set_log_stderr();
1075
1076         filename_tree = rbtree_create(filename_cmp, NULL, 0);
1077         if (!filename_tree) {
1078         oom:
1079                 ERROR("Out of memory");
1080                 exit(1);
1081         }
1082
1083         while ((c = getopt(argc, argv, "46c:d:D:f:Fhi:n:p:qr:sS:t:vx"
1084 #ifdef WITH_TCP
1085                 "P:"
1086 #endif
1087                            )) != EOF) switch(c) {
1088                 case '4':
1089                         force_af = AF_INET;
1090                         break;
1091                 case '6':
1092                         force_af = AF_INET6;
1093                         break;
1094                 case 'c':
1095                         if (!isdigit((int) *optarg))
1096                                 usage();
1097                         resend_count = atoi(optarg);
1098                         break;
1099                 case 'D':
1100                         dict_dir = optarg;
1101                         break;
1102                 case 'd':
1103                         radius_dir = optarg;
1104                         break;
1105                 case 'f':
1106                 {
1107                         char const *p;
1108                         rc_file_pair_t *files;
1109
1110                         files = talloc(talloc_autofree_context(), rc_file_pair_t);
1111                         if (!files) goto oom;
1112
1113                         p = strchr(optarg, ':');
1114                         if (p) {
1115                                 files->packets = talloc_strndup(files, optarg, p - optarg);
1116                                 if (!files->packets) goto oom;
1117                                 files->filters = p + 1;
1118                         } else {
1119                                 files->packets = optarg;
1120                                 files->filters = NULL;
1121                         }
1122                         rbtree_insert(filename_tree, (void *) files);
1123                 }
1124                         break;
1125                 case 'F':
1126                         print_filename = true;
1127                         break;
1128                 case 'i':       /* currently broken */
1129                         if (!isdigit((int) *optarg))
1130                                 usage();
1131                         last_used_id = atoi(optarg);
1132                         if ((last_used_id < 0) || (last_used_id > 255)) {
1133                                 usage();
1134                         }
1135                         break;
1136
1137                 case 'n':
1138                         persec = atoi(optarg);
1139                         if (persec <= 0) usage();
1140                         break;
1141
1142                         /*
1143                          *      Note that sending MANY requests in
1144                          *      parallel can over-run the kernel
1145                          *      queues, and Linux will happily discard
1146                          *      packets.  So even if the server responds,
1147                          *      the client may not see the reply.
1148                          */
1149                 case 'p':
1150                         parallel = atoi(optarg);
1151                         if (parallel <= 0) usage();
1152                         break;
1153
1154 #ifdef WITH_TCP
1155                 case 'P':
1156                         proto = optarg;
1157                         if (strcmp(proto, "tcp") != 0) {
1158                                 if (strcmp(proto, "udp") == 0) {
1159                                         proto = NULL;
1160                                 } else {
1161                                         usage();
1162                                 }
1163                         } else {
1164                                 ipproto = IPPROTO_TCP;
1165                         }
1166                         break;
1167
1168 #endif
1169
1170                 case 'q':
1171                         do_output = false;
1172                         fr_log_fp = NULL; /* no output from you, either! */
1173                         break;
1174
1175                 case 'r':
1176                         if (!isdigit((int) *optarg))
1177                                 usage();
1178                         retries = atoi(optarg);
1179                         if ((retries == 0) || (retries > 1000)) usage();
1180                         break;
1181                 case 's':
1182                         do_summary = true;
1183                         break;
1184                 case 'S':
1185                 {
1186                         char *p;
1187                         fp = fopen(optarg, "r");
1188                         if (!fp) {
1189                                ERROR("Error opening %s: %s", optarg, fr_syserror(errno));
1190                                exit(1);
1191                         }
1192                         if (fgets(filesecret, sizeof(filesecret), fp) == NULL) {
1193                                ERROR("Error reading %s: %s", optarg, fr_syserror(errno));
1194                                exit(1);
1195                         }
1196                         fclose(fp);
1197
1198                         /* truncate newline */
1199                         p = filesecret + strlen(filesecret) - 1;
1200                         while ((p >= filesecret) &&
1201                               (*p < ' ')) {
1202                                *p = '\0';
1203                                --p;
1204                         }
1205
1206                         if (strlen(filesecret) < 2) {
1207                                ERROR("Secret in %s is too short", optarg);
1208                                exit(1);
1209                         }
1210                         secret = filesecret;
1211                 }
1212                        break;
1213                 case 't':
1214                         if (!isdigit((int) *optarg))
1215                                 usage();
1216                         timeout = atof(optarg);
1217                         break;
1218                 case 'v':
1219                         DEBUG("%s", radclient_version);
1220                         exit(0);
1221                         break;
1222                 case 'x':
1223                         fr_debug_flag++;
1224                         rc_debug_flag++;
1225                         break;
1226                 case 'h':
1227                 default:
1228                         usage();
1229                         break;
1230         }
1231         argc -= (optind - 1);
1232         argv += (optind - 1);
1233
1234         if ((argc < 3)  || ((secret == NULL) && (argc < 4))) {
1235                 ERROR("Insufficient arguments");
1236                 usage();
1237         }
1238         /*
1239          *      Mismatch between the binary and the libraries it depends on
1240          */
1241         if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
1242                 fr_perror("radclient");
1243                 return 1;
1244         }
1245
1246         if (dict_init(dict_dir, RADIUS_DICTIONARY) < 0) {
1247                 fr_perror("radclient");
1248                 return 1;
1249         }
1250
1251         if (dict_read(radius_dir, RADIUS_DICTIONARY) == -1) {
1252                 fr_perror("radclient");
1253                 return 1;
1254         }
1255         fr_strerror();  /* Clear the error buffer */
1256
1257
1258         /*
1259          *      Get the request type
1260          */
1261         if (!isdigit((int) argv[2][0])) {
1262                 packet_code = fr_str2int(request_types, argv[2], -2);
1263                 if (packet_code == -2) {
1264                         ERROR("Unrecognised request type \"%s\"", argv[2]);
1265                         usage();
1266                 }
1267         } else {
1268                 packet_code = atoi(argv[2]);
1269         }
1270
1271         /*
1272          *      Resolve hostname.
1273          */
1274         if (force_af == AF_UNSPEC) force_af = AF_INET;
1275         server_ipaddr.af = force_af;
1276         if (strcmp(argv[1], "-") != 0) {
1277                 char *p;
1278                 char const *hostname = argv[1];
1279                 char const *portname = argv[1];
1280                 char buffer[256];
1281
1282                 if (*argv[1] == '[') { /* IPv6 URL encoded */
1283                         p = strchr(argv[1], ']');
1284                         if ((size_t) (p - argv[1]) >= sizeof(buffer)) {
1285                                 usage();
1286                         }
1287
1288                         memcpy(buffer, argv[1] + 1, p - argv[1] - 1);
1289                         buffer[p - argv[1] - 1] = '\0';
1290
1291                         hostname = buffer;
1292                         portname = p + 1;
1293
1294                 }
1295                 p = strchr(portname, ':');
1296                 if (p && (strchr(p + 1, ':') == NULL)) {
1297                         *p = '\0';
1298                         portname = p + 1;
1299                 } else {
1300                         portname = NULL;
1301                 }
1302
1303                 if (ip_hton(&server_ipaddr, force_af, hostname, false) < 0) {
1304                         ERROR("Failed to find IP address for host %s: %s", hostname, strerror(errno));
1305                         exit(1);
1306                 }
1307
1308                 /*
1309                  *      Strip port from hostname if needed.
1310                  */
1311                 if (portname) server_port = atoi(portname);
1312         }
1313
1314         radclient_get_port(packet_code, &server_port);
1315
1316         /*
1317          *      Add the secret.
1318          */
1319         if (argv[3]) secret = argv[3];
1320
1321         /*
1322          *      If no '-f' is specified, we're reading from stdin.
1323          */
1324         if (rbtree_num_elements(filename_tree) == 0) {
1325                 rc_file_pair_t *files;
1326
1327                 files = talloc_zero(talloc_autofree_context(), rc_file_pair_t);
1328                 files->packets = "stdin";
1329                 if (!radclient_init(files, files)) {
1330                         exit(1);
1331                 }
1332         }
1333
1334         /*
1335          *      Walk over the list of filenames, creating the requests.
1336          */
1337         if (rbtree_walk(filename_tree, RBTREE_IN_ORDER, filename_walk, NULL) != 0) {
1338                 ERROR("Failed parsing input files");
1339                 exit(1);
1340         }
1341
1342         /*
1343          *      No packets read.  Die.
1344          */
1345         if (!request_head) {
1346                 ERROR("Nothing to send");
1347                 exit(1);
1348         }
1349
1350         /*
1351          *      Bind to the first specified IP address and port.
1352          *      This means we ignore later ones.
1353          */
1354         if (request_head->packet->src_ipaddr.af == AF_UNSPEC) {
1355                 memset(&client_ipaddr, 0, sizeof(client_ipaddr));
1356                 client_ipaddr.af = server_ipaddr.af;
1357                 client_port = 0;
1358         } else {
1359                 client_ipaddr = request_head->packet->src_ipaddr;
1360                 client_port = request_head->packet->src_port;
1361         }
1362 #ifdef WITH_TCP
1363         if (proto) {
1364                 sockfd = fr_tcp_client_socket(NULL, &server_ipaddr, server_port);
1365         } else
1366 #endif
1367         sockfd = fr_socket(&client_ipaddr, client_port);
1368         if (sockfd < 0) {
1369                 ERROR("Error opening socket");
1370                 exit(1);
1371         }
1372
1373         pl = fr_packet_list_create(1);
1374         if (!pl) {
1375                 ERROR("Out of memory");
1376                 exit(1);
1377         }
1378
1379         if (!fr_packet_list_socket_add(pl, sockfd, ipproto, &server_ipaddr,
1380                                        server_port, NULL)) {
1381                 ERROR("Out of memory");
1382                 exit(1);
1383         }
1384
1385         /*
1386          *      Walk over the list of packets, sanity checking
1387          *      everything.
1388          */
1389         for (this = request_head; this != NULL; this = this->next) {
1390                 this->packet->src_ipaddr = client_ipaddr;
1391                 this->packet->src_port = client_port;
1392                 if (radclient_sane(this) != 0) {
1393                         exit(1);
1394                 }
1395         }
1396
1397         /*
1398          *      Walk over the packets to send, until
1399          *      we're all done.
1400          *
1401          *      FIXME: This currently busy-loops until it receives
1402          *      all of the packets.  It should really have some sort of
1403          *      send packet, get time to wait, select for time, etc.
1404          *      loop.
1405          */
1406         do {
1407                 int n = parallel;
1408                 rc_request_t *next;
1409                 char const *filename = NULL;
1410
1411                 done = true;
1412                 sleep_time = -1;
1413
1414                 /*
1415                  *      Walk over the packets, sending them.
1416                  */
1417
1418                 for (this = request_head; this != NULL; this = next) {
1419                         next = this->next;
1420
1421                         /*
1422                          *      If there's a packet to receive,
1423                          *      receive it, but don't wait for a
1424                          *      packet.
1425                          */
1426                         recv_one_packet(0);
1427
1428                         /*
1429                          *      This packet is done.  Delete it.
1430                          */
1431                         if (this->done) {
1432                                 talloc_free(this);
1433                                 continue;
1434                         }
1435
1436                         /*
1437                          *      Packets from multiple '-f' are sent
1438                          *      in parallel.
1439                          *
1440                          *      Packets from one file are sent in
1441                          *      series, unless '-p' is specified, in
1442                          *      which case N packets from each file
1443                          *      are sent in parallel.
1444                          */
1445                         if (this->files->packets != filename) {
1446                                 filename = this->files->packets;
1447                                 n = parallel;
1448                         }
1449
1450                         if (n > 0) {
1451                                 n--;
1452
1453                                 /*
1454                                  *      Send the current packet.
1455                                  */
1456                                 send_one_packet(this);
1457
1458                                 /*
1459                                  *      Wait a little before sending
1460                                  *      the next packet, if told to.
1461                                  */
1462                                 if (persec) {
1463                                         struct timeval tv;
1464
1465                                         /*
1466                                          *      Don't sleep elsewhere.
1467                                          */
1468                                         sleep_time = 0;
1469
1470                                         if (persec == 1) {
1471                                                 tv.tv_sec = 1;
1472                                                 tv.tv_usec = 0;
1473                                         } else {
1474                                                 tv.tv_sec = 0;
1475                                                 tv.tv_usec = 1000000/persec;
1476                                         }
1477
1478                                         /*
1479                                          *      Sleep for milliseconds,
1480                                          *      portably.
1481                                          *
1482                                          *      If we get an error or
1483                                          *      a signal, treat it like
1484                                          *      a normal timeout.
1485                                          */
1486                                         select(0, NULL, NULL, NULL, &tv);
1487                                 }
1488
1489                                 /*
1490                                  *      If we haven't sent this packet
1491                                  *      often enough, we're not done,
1492                                  *      and we shouldn't sleep.
1493                                  */
1494                                 if (this->resend < resend_count) {
1495                                         done = false;
1496                                         sleep_time = 0;
1497                                 }
1498                         } else { /* haven't sent this packet, we're not done */
1499                                 assert(this->done == false);
1500                                 assert(this->reply == NULL);
1501                                 done = false;
1502                         }
1503                 }
1504
1505                 /*
1506                  *      Still have outstanding requests.
1507                  */
1508                 if (fr_packet_list_num_elements(pl) > 0) {
1509                         done = false;
1510                 } else {
1511                         sleep_time = 0;
1512                 }
1513
1514                 /*
1515                  *      Nothing to do until we receive a request, so
1516                  *      sleep until then.  Once we receive one packet,
1517                  *      we go back, and walk through the whole list again,
1518                  *      sending more packets (if necessary), and updating
1519                  *      the sleep time.
1520                  */
1521                 if (!done && (sleep_time > 0)) {
1522                         recv_one_packet(sleep_time);
1523                 }
1524         } while (!done);
1525
1526         rbtree_free(filename_tree);
1527         fr_packet_list_free(pl);
1528         while (request_head) TALLOC_FREE(request_head);
1529         dict_free();
1530
1531         if (do_summary) {
1532                 DEBUG("Packet summary:\n"
1533                       "\tAccepted      : %" PRIu64 "\n"
1534                       "\tRejected      : %" PRIu64 "\n"
1535                       "\tLost          : %" PRIu64 "\n"
1536                       "\tPassed filter : %" PRIu64 "\n"
1537                       "\tFailed filter : %" PRIu64,
1538                       stats.accepted,
1539                       stats.rejected,
1540                       stats.lost,
1541                       stats.passed,
1542                       stats.failed
1543                 );
1544         }
1545
1546         if ((stats.lost > 0) || (stats.failed > 0)) {
1547                 exit(1);
1548         }
1549         exit(0);
1550 }