Release bumped to "gts4".
[tac_plus.git] / dump.c
1 /*
2    Copyright (c) 1995-1998 by Cisco systems, Inc.
3
4    Permission to use, copy, modify, and distribute this software for
5    any purpose and without fee is hereby granted, provided that this
6    copyright and permission notice appear on all copies of the
7    software and supporting documentation, the name of Cisco Systems,
8    Inc. not be used in advertising or publicity pertaining to
9    distribution of the program without specific prior permission, and
10    notice be given in supporting documentation that modification,
11    copying and distribution is by permission of Cisco Systems, Inc.
12
13    Cisco Systems, Inc. makes no representations about the suitability
14    of this software for any purpose.  THIS SOFTWARE IS PROVIDED ``AS
15    IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
16    WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17    FITNESS FOR A PARTICULAR PURPOSE.
18 */
19
20
21 #include "tac_plus.h"
22
23 #include <netinet/in.h>         /* for ntohl() */
24
25 #include "dump.h"
26 #include "report.h"
27 #include "utils.h"
28 #include "packet.h"
29 #include "do_author.h"
30 #include "main.h"
31
32
33 char *summarise_outgoing_packet_type TAC_ARGS((u_char *pak));
34
35 /* Routines for dumping packets to stderr */
36 char *
37 summarise_outgoing_packet_type(pak)
38 u_char *pak;
39 {
40     HDR *hdr;
41     struct authen_reply *authen;
42     struct author_reply *author;
43     char *p;
44
45     hdr = (HDR *) pak;
46
47     switch (hdr->type) {
48     case TAC_PLUS_AUTHEN:
49         authen = (struct authen_reply *) (pak + TAC_PLUS_HDR_SIZE);
50
51         switch (authen->status) {
52         case TAC_PLUS_AUTHEN_STATUS_PASS:
53             p = "AUTHEN/SUCCEED";
54             break;
55         case TAC_PLUS_AUTHEN_STATUS_FAIL:
56             p = "AUTHEN/FAIL";
57             break;
58         case TAC_PLUS_AUTHEN_STATUS_GETDATA:
59             p = "AUTHEN/GETDATA";
60             break;
61         case TAC_PLUS_AUTHEN_STATUS_GETUSER:
62             p = "AUTHEN/GETUSER";
63             break;
64         case TAC_PLUS_AUTHEN_STATUS_GETPASS:
65             p = "AUTHEN/GETPASS";
66             break;
67         case TAC_PLUS_AUTHEN_STATUS_ERROR:
68             p = "AUTHEN/ERROR";
69             break;
70         default:
71             p = "AUTHEN/UNKNOWN";
72             break;
73         }
74         break;
75
76     case TAC_PLUS_AUTHOR:
77         author = (struct author_reply *) (pak + TAC_PLUS_HDR_SIZE);
78         switch (author->status) {
79         case AUTHOR_STATUS_PASS_ADD:
80             p = "AUTHOR/PASS_ADD";
81             break;
82         case AUTHOR_STATUS_FAIL:
83             p = "AUTHOR/FAIL";
84             break;
85         case AUTHOR_STATUS_PASS_REPL:
86             p = "AUTHOR/PASS_REPL";
87             break;
88         case AUTHOR_STATUS_ERROR:
89             p = "AUTHOR/ERROR";
90             break;
91         default:
92             p = "AUTHOR/UNKNOWN";
93             break;
94         }
95         break;
96     case TAC_PLUS_ACCT:
97         p = "ACCT";
98         break;
99     default:
100         p = "UNKNOWN";
101         break;
102     }
103     return (p);
104 }
105
106 static void dump_header TAC_ARGS((u_char *pak));
107
108 static void
109 dump_header(pak)
110 u_char *pak;
111 {
112     HDR *hdr;
113     u_char *data;
114
115     hdr = (HDR *) pak;
116
117     report(LOG_DEBUG, "PACKET: key=%s", session.key ? session.key : "<NULL>");
118     report(LOG_DEBUG, "version %d (0x%x), type %d, seq no %d, encryption %d",
119            hdr->version, hdr->version,
120            hdr->type, hdr->seq_no, hdr->encryption);
121     report(LOG_DEBUG, "session_id %u (0x%x), Data length %d (0x%x)",
122            ntohl(hdr->session_id), ntohl(hdr->session_id),
123            ntohl(hdr->datalength), ntohl(hdr->datalength));
124
125     report(LOG_DEBUG, "End header");
126
127     if (debug & DEBUG_HEX_FLAG) {
128         report(LOG_DEBUG, "Packet body hex dump:");
129         data = (u_char *) (pak + TAC_PLUS_HDR_SIZE);
130         report_hex(LOG_DEBUG, data, ntohl(hdr->datalength));
131     }
132 }
133
134
135 void dump_nas_pak TAC_ARGS((u_char *pak));
136
137 /* Dump packets originated by a NAS */
138 void
139 dump_nas_pak(pak)
140 u_char *pak;
141 {
142     struct authen_start *start;
143     struct authen_cont *cont;
144     struct author *author;
145     struct acct *acct;
146     int i;
147     HDR *hdr;
148     u_char *p, *argsizep;
149     int seq;
150
151     dump_header(pak);
152
153     hdr = (HDR *) pak;
154
155     seq = hdr->seq_no;
156     if (seq % 2 != 1) {
157         report(LOG_DEBUG, "nas packets should be odd numbered seq=%d",
158                seq);
159         exit(1);
160     }
161     switch (hdr->type) {
162
163     case TAC_PLUS_AUTHEN:
164         start = (struct authen_start *) (pak + TAC_PLUS_HDR_SIZE);
165
166         switch (hdr->seq_no) {
167
168         case 1:
169             report(LOG_DEBUG, "type=AUTHEN/START, priv_lvl = %d",
170                    start->priv_lvl);
171
172             switch (start->action) {
173             case TAC_PLUS_AUTHEN_LOGIN:
174                 report(LOG_DEBUG, "action=login");
175                 break;
176             case TAC_PLUS_AUTHEN_CHPASS:
177                 report(LOG_DEBUG, "action=chpass");
178                 break;
179             case TAC_PLUS_AUTHEN_SENDPASS:
180                 report(LOG_DEBUG, "action=sendpass");
181                 break;
182             case TAC_PLUS_AUTHEN_SENDAUTH:
183                 report(LOG_DEBUG, "action=sendauth");
184                 break;
185             default:
186                 report(LOG_DEBUG, "action=UNKNOWN %d", start->action);
187                 break;
188             }
189
190             switch(start->authen_type) {
191             case TAC_PLUS_AUTHEN_TYPE_ASCII:
192                 report(LOG_DEBUG, "authen_type=ascii");
193                 break;
194             case TAC_PLUS_AUTHEN_TYPE_PAP:
195                 report(LOG_DEBUG, "authen_type=pap");
196                 break;
197             case TAC_PLUS_AUTHEN_TYPE_CHAP:
198                 report(LOG_DEBUG, "authen_type=chap");
199                 break;
200             case TAC_PLUS_AUTHEN_TYPE_ARAP:
201                 report(LOG_DEBUG, "authen_type=arap");
202                 break;
203             default:
204                 report(LOG_DEBUG, "authen_type=unknown %d", start->authen_type);
205                 break;
206             }
207
208             switch(start->service) {
209
210             case TAC_PLUS_AUTHEN_SVC_LOGIN:
211                 report(LOG_DEBUG, "service=login");
212                 break;
213             case TAC_PLUS_AUTHEN_SVC_ENABLE:
214                 report(LOG_DEBUG, "service=enable");
215                 break;
216             case TAC_PLUS_AUTHEN_SVC_PPP:
217                 report(LOG_DEBUG, "service=ppp");
218                 break;
219             case TAC_PLUS_AUTHEN_SVC_ARAP:
220                 report(LOG_DEBUG, "service=arap");
221                 break;
222             case TAC_PLUS_AUTHEN_SVC_PT:
223                 report(LOG_DEBUG, "service=pt");
224                 break;
225             case TAC_PLUS_AUTHEN_SVC_RCMD:
226                 report(LOG_DEBUG, "service=rcmd");
227                 break;
228             case TAC_PLUS_AUTHEN_SVC_X25:
229                 report(LOG_DEBUG, "service=x25");
230                 break;
231             case TAC_PLUS_AUTHEN_SVC_NASI:
232                 report(LOG_DEBUG, "service=nasi");
233                 break;
234             default:
235                 report(LOG_DEBUG, "service=unknown %d", start->service);
236                 break;
237             }
238
239             report(LOG_DEBUG,
240                    "user_len=%d port_len=%d (0x%x), rem_addr_len=%d (0x%x)",
241                    start->user_len, start->port_len, start->port_len,
242                    start->rem_addr_len, start->rem_addr_len);
243
244             report(LOG_DEBUG, "data_len=%d", start->data_len);
245
246             /* start of variable length data is here */
247             p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHEN_START_FIXED_FIELDS_SIZE;
248
249             report(LOG_DEBUG, "User: ");
250             report_string(LOG_DEBUG, p, start->user_len);
251             p += start->user_len;
252
253             report(LOG_DEBUG, "port: ");
254             report_string(LOG_DEBUG, p, start->port_len);
255             p += start->port_len;
256
257             report(LOG_DEBUG, "rem_addr: ");
258             report_string(LOG_DEBUG, p, start->rem_addr_len);
259             p += start->rem_addr_len;
260
261             report(LOG_DEBUG, "data: ");
262             report_string(LOG_DEBUG, p, start->data_len);
263
264             report(LOG_DEBUG, "End packet");
265             return;
266
267         default:
268             cont = (struct authen_cont *) (pak + TAC_PLUS_HDR_SIZE);
269             report(LOG_DEBUG, "type=AUTHEN/CONT");
270             report(LOG_DEBUG, "user_msg_len %d (0x%x), user_data_len %d (0x%x)",
271                    cont->user_msg_len, cont->user_msg_len,
272                    cont->user_data_len, cont->user_data_len);
273             report(LOG_DEBUG, "flags=0x%x", cont->flags);
274
275             /* start of variable length data is here */
276             p = pak + TAC_PLUS_HDR_SIZE +
277                 TAC_AUTHEN_CONT_FIXED_FIELDS_SIZE;
278
279             report(LOG_DEBUG, "User msg: ");
280             report_string(LOG_DEBUG, p, cont->user_msg_len);
281             p += cont->user_msg_len;
282
283             report(LOG_DEBUG, "User data: ");
284             report_string(LOG_DEBUG, p, cont->user_data_len);
285
286             report(LOG_DEBUG, "End packet");
287             return;
288         }
289
290     case TAC_PLUS_AUTHOR:
291         author = (struct author *) (pak + TAC_PLUS_HDR_SIZE);
292
293         report(LOG_DEBUG, "type=AUTHOR, priv_lvl=%d, authen=%d",
294                author->priv_lvl,
295                author->authen_type);
296
297         switch(author->authen_method) {
298         case AUTHEN_METH_NONE:
299                 report(LOG_DEBUG, "method=none");
300                 break;
301         case AUTHEN_METH_KRB5:
302                 report(LOG_DEBUG, "method=krb5");
303                 break;
304         case AUTHEN_METH_LINE:
305                 report(LOG_DEBUG, "method=line");
306                 break;
307         case AUTHEN_METH_ENABLE:
308                 report(LOG_DEBUG, "method=enable");
309                 break;
310         case AUTHEN_METH_LOCAL:
311                 report(LOG_DEBUG, "method=local");
312                 break;
313         case AUTHEN_METH_TACACSPLUS:
314                 report(LOG_DEBUG, "method=tacacs+");
315                 break;
316         case AUTHEN_METH_RCMD:
317                 report(LOG_DEBUG, "method=rcmd");
318                 break;
319         default:
320                 report(LOG_DEBUG, "method=unknown %d", author->authen_method);
321                 break;
322         }
323
324         report(LOG_DEBUG, "svc=%d user_len=%d port_len=%d rem_addr_len=%d",
325                author->service, author->user_len,
326                author->port_len, author->rem_addr_len);
327
328         report(LOG_DEBUG, "arg_cnt=%d", author->arg_cnt);
329
330         /* variable length data start here */
331         p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REQ_FIXED_FIELDS_SIZE;
332         argsizep = p;
333         p += author->arg_cnt;
334
335         report(LOG_DEBUG, "User: ");
336         report_string(LOG_DEBUG, p, author->user_len);
337         p += author->user_len;
338
339         report(LOG_DEBUG, "port: ");
340         report_string(LOG_DEBUG, p, author->port_len);
341         p += author->port_len;
342
343         report(LOG_DEBUG, "rem_addr: ");
344         report_string(LOG_DEBUG, p, author->rem_addr_len);
345         p += author->rem_addr_len;
346
347         for (i = 0; i < (int) author->arg_cnt; i++) {
348             report(LOG_DEBUG, "arg[%d]: size=%d ", i, *argsizep);
349             report_string(LOG_DEBUG, p, *argsizep);
350             p += *argsizep;
351             argsizep++;
352         }
353         break;
354
355     case TAC_PLUS_ACCT:
356         acct = (struct acct *) (pak + TAC_PLUS_HDR_SIZE);
357         report(LOG_DEBUG, "ACCT, flags=0x%x method=%d priv_lvl=%d",
358                acct->flags, acct->authen_method, acct->priv_lvl);
359         report(LOG_DEBUG, "type=%d svc=%d",
360                acct->authen_type, acct->authen_service);
361         report(LOG_DEBUG, "user_len=%d port_len=%d rem_addr_len=%d",
362                acct->user_len, acct->port_len, acct->rem_addr_len);
363         report(LOG_DEBUG, "arg_cnt=%d", acct->arg_cnt);
364
365         p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REQ_FIXED_FIELDS_SIZE;
366         argsizep = p;
367         p += acct->arg_cnt;
368
369         report(LOG_DEBUG, "User: ");
370         report_string(LOG_DEBUG, p, acct->user_len);
371         p += acct->user_len;
372
373         report(LOG_DEBUG, "port: ");
374         report_string(LOG_DEBUG, p, acct->port_len);
375         p += acct->port_len;
376
377         report(LOG_DEBUG, "rem_addr: ");
378         report_string(LOG_DEBUG, p, acct->rem_addr_len);
379         p += acct->rem_addr_len;
380
381         for (i = 0; i < (int) acct->arg_cnt; i++) {
382             report(LOG_DEBUG, "arg[%d]: size=%d ", i, *argsizep);
383             report_string(LOG_DEBUG, p, *argsizep);
384             p += *argsizep;
385             argsizep++;
386         }
387         break;
388
389     default:
390         report(LOG_DEBUG, "dump_nas_pak: unrecognized header type %d", hdr->type);
391     }
392     report(LOG_DEBUG, "End packet");
393 }
394
395 /* Dump packets originated by Tacacsd  */
396
397 void dump_tacacs_pak TAC_ARGS((u_char *pak));
398
399 void
400 dump_tacacs_pak(pak)
401 u_char *pak;
402 {
403     struct authen_reply *authen;
404     struct author_reply *author;
405     struct acct_reply *acct;
406     HDR *hdr;
407     u_char *p, *argsizep;
408     int i;
409     int seq;
410
411     dump_header(pak);
412
413     hdr = (HDR *) pak;
414     seq = hdr->seq_no;
415
416     if (seq % 2 != 0) {
417         report(LOG_ERR, "%s: Bad sequence number %d should be even",
418                session.peer, seq);
419         tac_exit(1);
420     }
421     switch (hdr->type) {
422
423     case TAC_PLUS_AUTHEN:
424         authen = (struct authen_reply *) (pak + TAC_PLUS_HDR_SIZE);
425
426         report(LOG_DEBUG, "type=AUTHEN status=%d (%s) flags=0x%x",
427                authen->status, summarise_outgoing_packet_type(pak),
428                authen->flags);
429
430         report(LOG_DEBUG, "msg_len=%d, data_len=%d",
431                authen->msg_len, authen->data_len);
432
433         /* start of variable length data is here */
434         p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHEN_REPLY_FIXED_FIELDS_SIZE;
435
436         report(LOG_DEBUG, "msg: ");
437         report_string(LOG_DEBUG, p, authen->msg_len);
438         p += authen->msg_len;
439
440         report(LOG_DEBUG, "data: ");
441         report_string(LOG_DEBUG, p, authen->data_len);
442
443         report(LOG_DEBUG, "End packet");
444         return;
445
446     case TAC_PLUS_AUTHOR:
447         author = (struct author_reply *) (pak + TAC_PLUS_HDR_SIZE);
448
449         report(LOG_DEBUG, "type=AUTHOR/REPLY status=%d (%s) ",
450                author->status, summarise_outgoing_packet_type(pak));
451         report(LOG_DEBUG, "msg_len=%d, data_len=%d arg_cnt=%d",
452                author->msg_len, author->data_len, author->arg_cnt);
453
454         /* start of variable length data is here */
455         p = pak + TAC_PLUS_HDR_SIZE + TAC_AUTHOR_REPLY_FIXED_FIELDS_SIZE;
456
457         /* arg sizes come next */
458         argsizep = p;
459
460         p += author->arg_cnt;
461
462         report(LOG_DEBUG, "msg: ");
463         report_string(LOG_DEBUG, p, author->msg_len);
464         p += author->msg_len;
465
466         report(LOG_DEBUG, "data: ");
467         report_string(LOG_DEBUG, p, author->data_len);
468         p += author->data_len;
469
470         /* args follow */
471         for (i = 0; i < (int) author->arg_cnt; i++) {
472             int size = argsizep[i];
473
474             report(LOG_DEBUG, "arg[%d] size=%d ", i, size);
475             report_string(LOG_DEBUG, p, size);
476             p += size;
477         }
478         break;
479
480     case TAC_PLUS_ACCT:
481         acct = (struct acct_reply *) (pak + TAC_PLUS_HDR_SIZE);
482         report(LOG_DEBUG, "ACCT/REPLY status=%d", acct->status);
483
484         report(LOG_DEBUG, "msg_len=%d data_len=%d",
485                acct->msg_len, acct->data_len);
486
487         p = pak + TAC_PLUS_HDR_SIZE + TAC_ACCT_REPLY_FIXED_FIELDS_SIZE;
488
489         report(LOG_DEBUG, "msg: ");
490
491         report_string(LOG_DEBUG, p, acct->msg_len);
492         p += acct->msg_len;
493
494         report(LOG_DEBUG, "data: ");
495         report_string(LOG_DEBUG, p, acct->data_len);
496
497         break;
498
499     default:
500         report(LOG_DEBUG, "dump_tacacs_pak: unrecognized header type %d",
501                hdr->type);
502     }
503     report(LOG_DEBUG, "End packet");
504 }
505
506 char *summarise_incoming_packet_type TAC_ARGS((u_char *pak));
507
508 /* summarise packet types for logging routines. */
509 char *
510 summarise_incoming_packet_type(pak)
511 u_char *pak;
512 {
513     HDR *hdr;
514     char *p;
515
516     hdr = (HDR *) pak;
517
518     switch (hdr->type) {
519     case TAC_PLUS_AUTHEN:
520         switch (hdr->seq_no) {
521         case 1:
522             p = "AUTHEN/START";
523             break;
524         default:
525             p = "AUTHEN/CONT";
526             break;
527         }
528         return (p);
529
530     case TAC_PLUS_AUTHOR:
531         p = "AUTHOR";
532         break;
533     case TAC_PLUS_ACCT:
534         p = "ACCT";
535         break;
536     default:
537         p = "UNKNOWN";
538         break;
539     }
540     return (p);
541 }