print-krb.c revision 56893
1112918Sjeff/*
2112918Sjeff * Copyright (c) 1995, 1996, 1997
3112918Sjeff *	The Regents of the University of California.  All rights reserved.
4112918Sjeff *
5112918Sjeff * Redistribution and use in source and binary forms, with or without
6112918Sjeff * modification, are permitted provided that: (1) source code distributions
7112918Sjeff * retain the above copyright notice and this paragraph in its entirety, (2)
8112918Sjeff * distributions including binary code include the above copyright notice and
9112918Sjeff * this paragraph in its entirety in the documentation or other materials
10112918Sjeff * provided with the distribution, and (3) all advertising materials mentioning
11112918Sjeff * features or use of this software display the following acknowledgement:
12112918Sjeff * ``This product includes software developed by the University of California,
13112918Sjeff * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14112918Sjeff * the University nor the names of its contributors may be used to endorse
15112918Sjeff * or promote products derived from this software without specific prior
16112918Sjeff * written permission.
17112918Sjeff * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18112918Sjeff * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19112918Sjeff * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20112918Sjeff *
21112918Sjeff * Initial contribution from John Hawkinson (jhawk@mit.edu).
22112918Sjeff */
23112918Sjeff
24112918Sjeff#ifndef lint
25112918Sjeffstatic const char rcsid[] =
26112918Sjeff    "@(#) $Header: /tcpdump/master/tcpdump/print-krb.c,v 1.12 1999/11/21 09:36:55 fenner Exp $";
27144518Sdavidxu#endif
28297706Skib
29297706Skib#ifdef HAVE_CONFIG_H
30297706Skib#include "config.h"
31112918Sjeff#endif
32112918Sjeff
33112918Sjeff#include <sys/param.h>
34217224Skib#include <sys/time.h>
35217224Skib#include <sys/socket.h>
36112918Sjeff
37112918Sjeff#include <netinet/in.h>
38217191Skib#include <netinet/in_systm.h>
39144518Sdavidxu#include <netinet/ip.h>
40112918Sjeff#include <netinet/ip_var.h>
41112918Sjeff#include <netinet/udp.h>
42112918Sjeff#include <netinet/udp_var.h>
43112918Sjeff
44112918Sjeff#include <ctype.h>
45112918Sjeff#include <errno.h>
46112918Sjeff#include <stdio.h>
47112918Sjeff
48112918Sjeff#include "interface.h"
49112918Sjeff#include "addrtoname.h"
50112918Sjeff
51144518Sdavidxuconst u_char *c_print(register const u_char *, register const u_char *);
52144518Sdavidxuconst u_char *krb4_print_hdr(const u_char *);
53144518Sdavidxuvoid krb4_print(const u_char *);
54112918Sjeffvoid krb_print(const u_char *, u_int);
55144518Sdavidxu
56112918Sjeff
57112918Sjeff#define AUTH_MSG_KDC_REQUEST			1<<1
58112918Sjeff#define AUTH_MSG_KDC_REPLY			2<<1
59144518Sdavidxu#define AUTH_MSG_APPL_REQUEST			3<<1
60144518Sdavidxu#define AUTH_MSG_APPL_REQUEST_MUTUAL		4<<1
61144518Sdavidxu#define AUTH_MSG_ERR_REPLY			5<<1
62144518Sdavidxu#define AUTH_MSG_PRIVATE			6<<1
63112918Sjeff#define AUTH_MSG_SAFE				7<<1
64144518Sdavidxu#define AUTH_MSG_APPL_ERR			8<<1
65112918Sjeff#define AUTH_MSG_DIE				63<<1
66112918Sjeff
67144518Sdavidxu#define KERB_ERR_OK				0
68144518Sdavidxu#define KERB_ERR_NAME_EXP			1
69144518Sdavidxu#define KERB_ERR_SERVICE_EXP			2
70144518Sdavidxu#define KERB_ERR_AUTH_EXP			3
71144518Sdavidxu#define KERB_ERR_PKT_VER			4
72144518Sdavidxu#define KERB_ERR_NAME_MAST_KEY_VER		5
73144518Sdavidxu#define KERB_ERR_SERV_MAST_KEY_VER		6
74144518Sdavidxu#define KERB_ERR_BYTE_ORDER			7
75144518Sdavidxu#define KERB_ERR_PRINCIPAL_UNKNOWN		8
76144518Sdavidxu#define KERB_ERR_PRINCIPAL_NOT_UNIQUE		9
77112918Sjeff#define KERB_ERR_NULL_KEY			10
78112918Sjeff
79112918Sjeffstruct krb {
80112918Sjeff	u_char pvno;		/* Protocol Version */
81112918Sjeff	u_char type;		/* Type+B */
82112918Sjeff};
83112918Sjeff
84112918Sjeffstatic char tstr[] = " [|kerberos]";
85112918Sjeff
86112918Sjeffstatic struct tok type2str[] = {
87144518Sdavidxu	{ AUTH_MSG_KDC_REQUEST,		"KDC_REQUEST" },
88112918Sjeff	{ AUTH_MSG_KDC_REPLY,		"KDC_REPLY" },
89112918Sjeff	{ AUTH_MSG_APPL_REQUEST,	"APPL_REQUEST" },
90112918Sjeff	{ AUTH_MSG_APPL_REQUEST_MUTUAL,	"APPL_REQUEST_MUTUAL" },
91112918Sjeff	{ AUTH_MSG_ERR_REPLY,		"ERR_REPLY" },
92112918Sjeff	{ AUTH_MSG_PRIVATE,		"PRIVATE" },
93112918Sjeff	{ AUTH_MSG_SAFE,		"SAFE" },
94112918Sjeff	{ AUTH_MSG_APPL_ERR,		"APPL_ERR" },
95112918Sjeff	{ AUTH_MSG_DIE,			"DIE" },
96112918Sjeff	{ 0,				NULL }
97112918Sjeff};
98144518Sdavidxu
99112918Sjeffstatic struct tok kerr2str[] = {
100112918Sjeff	{ KERB_ERR_OK,			"OK" },
101112918Sjeff	{ KERB_ERR_NAME_EXP,		"NAME_EXP" },
102112918Sjeff	{ KERB_ERR_SERVICE_EXP,		"SERVICE_EXP" },
103112918Sjeff	{ KERB_ERR_AUTH_EXP,		"AUTH_EXP" },
104112918Sjeff	{ KERB_ERR_PKT_VER,		"PKT_VER" },
105112918Sjeff	{ KERB_ERR_NAME_MAST_KEY_VER,	"NAME_MAST_KEY_VER" },
106112918Sjeff	{ KERB_ERR_SERV_MAST_KEY_VER,	"SERV_MAST_KEY_VER" },
107112918Sjeff	{ KERB_ERR_BYTE_ORDER,		"BYTE_ORDER" },
108112918Sjeff	{ KERB_ERR_PRINCIPAL_UNKNOWN,	"PRINCIPAL_UNKNOWN" },
109144518Sdavidxu	{ KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" },
110112918Sjeff	{ KERB_ERR_NULL_KEY,		"NULL_KEY"},
111112918Sjeff	{ 0,				NULL}
112112918Sjeff};
113112918Sjeff
114112918Sjeff
115112918Sjeff/* little endian (unaligned) to host byte order */
116112918Sjeff/* XXX need to look at this... */
117112918Sjeff#define vtohlp(x)	    ((( ((char *)(x))[0] )      )  | \
118112918Sjeff			     (( ((char *)(x))[1] ) <<  8)  | \
119112918Sjeff			     (( ((char *)(x))[2] ) << 16)  | \
120157457Sdavidxu			     (( ((char *)(x))[3] ) << 24))
121112918Sjeff#define vtohsp(x)          ((( ((char *)(x))[0] )      )  | \
122144518Sdavidxu			     (( ((char *)(x))[1] ) <<  8))
123144518Sdavidxu/* network (big endian) (unaligned) to host byte order */
124144518Sdavidxu#define ntohlp(x)	    ((( ((char *)(x))[3] )      )  | \
125144518Sdavidxu			     (( ((char *)(x))[2] ) <<  8)  | \
126144518Sdavidxu			     (( ((char *)(x))[1] ) << 16)  | \
127144518Sdavidxu			     (( ((char *)(x))[0] ) << 24))
128112918Sjeff#define ntohsp(x)          ((( ((char *)(x))[1] )      )  | \
129144518Sdavidxu			     (( ((char *)(x))[0] ) <<  8))
130144518Sdavidxu
131144518Sdavidxu
132144518Sdavidxu
133144518Sdavidxuconst u_char *
134112918Sjeffc_print(register const u_char *s, register const u_char *ep)
135217191Skib{
136217191Skib	register u_char c;
137217191Skib	register int flag;
138217191Skib
139217191Skib	flag = 1;
140217191Skib	while (s < ep) {
141217191Skib		c = *s++;
142217191Skib		if (c == '\0') {
143217191Skib			flag = 0;
144217191Skib			break;
145217224Skib		}
146217224Skib		if (!isascii(c)) {
147217224Skib			c = toascii(c);
148217224Skib			putchar('M');
149217224Skib			putchar('-');
150217224Skib		}
151217224Skib		if (!isprint(c)) {
152217224Skib			c ^= 0x40;	/* DEL to ?, others to alpha */
153217224Skib			putchar('^');
154217224Skib		}
155217224Skib		putchar(c);
156217224Skib	}
157217224Skib	if (flag)
158217224Skib		return NULL;
159217224Skib	return (s);
160217224Skib}
161217224Skib
162217224Skibconst u_char *
163217224Skibkrb4_print_hdr(const u_char *cp)
164217224Skib{
165217191Skib	cp += 2;
166295407Skib
167217191Skib#define PRINT		if ((cp = c_print(cp, snapend)) == NULL) goto trunc
168217191Skib
169217191Skib	PRINT;
170217191Skib	putchar('.');
171217224Skib	PRINT;
172217224Skib	putchar('@');
173217224Skib	PRINT;
174217224Skib	return (cp);
175217191Skib
176217191Skibtrunc:
177217191Skib	fputs(tstr, stdout);
178217191Skib	return (NULL);
179217191Skib
180217191Skib#undef PRINT
181217191Skib}
182217191Skib
183217191Skibvoid
184217191Skibkrb4_print(const u_char *cp)
185217191Skib{
186217191Skib	register const struct krb *kp;
187217191Skib	u_char type;
188217191Skib	u_short len;
189217191Skib
190144518Sdavidxu#define PRINT		if ((cp = c_print(cp, snapend)) == NULL) goto trunc
191144518Sdavidxu/*  True if struct krb is little endian */
192144518Sdavidxu#define IS_LENDIAN(kp)	(((kp)->type & 0x01) != 0)
193144518Sdavidxu#define KTOHSP(kp, cp)	(IS_LENDIAN(kp) ? vtohsp(cp) : ntohsp(cp))
194144518Sdavidxu
195144518Sdavidxu	kp = (struct krb *)cp;
196144518Sdavidxu
197144518Sdavidxu	if ((&kp->type) >= snapend) {
198144518Sdavidxu		fputs(tstr, stdout);
199112918Sjeff		return;
200144518Sdavidxu	}
201144518Sdavidxu
202144518Sdavidxu	type = kp->type & (0xFF << 1);
203144518Sdavidxu
204144518Sdavidxu	printf(" %s %s: ",
205112918Sjeff	    IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type));
206144518Sdavidxu
207144518Sdavidxu	switch (type) {
208112918Sjeff
209144518Sdavidxu	case AUTH_MSG_KDC_REQUEST:
210144518Sdavidxu		if ((cp = krb4_print_hdr(cp)) == NULL)
211144518Sdavidxu			return;
212112918Sjeff		cp += 4;	/* ctime */
213144518Sdavidxu		TCHECK(*cp);
214144518Sdavidxu		printf(" %dmin ", *cp++ * 5);
215144518Sdavidxu		PRINT;
216212536Sdavidxu		putchar('.');
217144518Sdavidxu		PRINT;
218112918Sjeff		break;
219112918Sjeff
220112918Sjeff	case AUTH_MSG_APPL_REQUEST:
221144518Sdavidxu		cp += 2;
222144518Sdavidxu		TCHECK(*cp);
223144518Sdavidxu		printf("v%d ", *cp++);
224144518Sdavidxu		PRINT;
225112918Sjeff		TCHECK(*cp);
226144518Sdavidxu		printf(" (%d)", *cp++);
227112918Sjeff		TCHECK(*cp);
228112918Sjeff		printf(" (%d)", *cp);
229112918Sjeff		break;
230112918Sjeff
231112918Sjeff	case AUTH_MSG_KDC_REPLY:
232112918Sjeff		if ((cp = krb4_print_hdr(cp)) == NULL)
233112918Sjeff			return;
234112918Sjeff		cp += 10;	/* timestamp + n + exp + kvno */
235144518Sdavidxu		TCHECK2(*cp, sizeof(short));
236144518Sdavidxu		len = KTOHSP(kp, cp);
237112918Sjeff		printf(" (%d)", len);
238112918Sjeff		break;
239144518Sdavidxu
240112918Sjeff	case AUTH_MSG_ERR_REPLY:
241112918Sjeff		if ((cp = krb4_print_hdr(cp)) == NULL)
242112918Sjeff			return;
243112918Sjeff		cp += 4; 	  /* timestamp */
244144518Sdavidxu		TCHECK2(*cp, sizeof(short));
245144518Sdavidxu		printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)));
246144518Sdavidxu		cp += 4;
247144518Sdavidxu		PRINT;
248144518Sdavidxu		break;
249269909Skib
250269909Skib	default:
251269909Skib		fputs("(unknown)", stdout);
252269909Skib		break;
253112918Sjeff	}
254144518Sdavidxu
255144518Sdavidxu	return;
256112918Sjefftrunc:
257112918Sjeff	fputs(tstr, stdout);
258144518Sdavidxu}
259112918Sjeff
260112918Sjeffvoid
261144518Sdavidxukrb_print(const u_char *dat, u_int length)
262144518Sdavidxu{
263112918Sjeff	register const struct krb *kp;
264144518Sdavidxu
265144518Sdavidxu	kp = (struct krb *)dat;
266112918Sjeff
267144518Sdavidxu	if (dat >= snapend) {
268112918Sjeff		fputs(tstr, stdout);
269144518Sdavidxu		return;
270144518Sdavidxu	}
271144518Sdavidxu
272144518Sdavidxu	switch (kp->pvno) {
273144518Sdavidxu
274269908Skib	case 1:
275217191Skib	case 2:
276144518Sdavidxu	case 3:
277144518Sdavidxu		printf(" v%d", kp->pvno);
278144518Sdavidxu		break;
279144518Sdavidxu
280144518Sdavidxu	case 4:
281144518Sdavidxu		printf(" v%d", kp->pvno);
282144518Sdavidxu		krb4_print((const u_char *)kp);
283144518Sdavidxu		break;
284144518Sdavidxu
285144518Sdavidxu	case 106:
286112918Sjeff	case 107:
287144518Sdavidxu		fputs(" v5", stdout);
288144518Sdavidxu		/* Decode ASN.1 here "someday" */
289144518Sdavidxu		break;
290144518Sdavidxu	}
291112918Sjeff	return;
292112918Sjeff}
293144518Sdavidxu