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