xref: /freebsd/contrib/tcpdump/print-krb.c (revision 4644f044b29b71b385396356b7cbf92b09e67628)
14edb46e9SPaul Traina /*
24644f044SBill Fenner  * Copyright (c) 1995, 1996, 1997
34edb46e9SPaul Traina  *	The Regents of the University of California.  All rights reserved.
44edb46e9SPaul Traina  *
54edb46e9SPaul Traina  * Redistribution and use in source and binary forms, with or without
64edb46e9SPaul Traina  * modification, are permitted provided that: (1) source code distributions
74edb46e9SPaul Traina  * retain the above copyright notice and this paragraph in its entirety, (2)
84edb46e9SPaul Traina  * distributions including binary code include the above copyright notice and
94edb46e9SPaul Traina  * this paragraph in its entirety in the documentation or other materials
104edb46e9SPaul Traina  * provided with the distribution, and (3) all advertising materials mentioning
114edb46e9SPaul Traina  * features or use of this software display the following acknowledgement:
124edb46e9SPaul Traina  * ``This product includes software developed by the University of California,
134edb46e9SPaul Traina  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
144edb46e9SPaul Traina  * the University nor the names of its contributors may be used to endorse
154edb46e9SPaul Traina  * or promote products derived from this software without specific prior
164edb46e9SPaul Traina  * written permission.
174edb46e9SPaul Traina  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
184edb46e9SPaul Traina  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
194edb46e9SPaul Traina  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
204edb46e9SPaul Traina  *
214edb46e9SPaul Traina  * Initial contribution from John Hawkinson (jhawk@mit.edu).
224edb46e9SPaul Traina  */
234edb46e9SPaul Traina 
244edb46e9SPaul Traina #ifndef lint
254de76e31SBill Fenner static const char rcsid[] =
264644f044SBill Fenner     "@(#) $Header: print-krb.c,v 1.9 97/04/26 14:01:45 leres Exp $";
274edb46e9SPaul Traina #endif
284edb46e9SPaul Traina 
294edb46e9SPaul Traina #include <sys/param.h>
304edb46e9SPaul Traina #include <sys/time.h>
314edb46e9SPaul Traina #include <sys/socket.h>
324edb46e9SPaul Traina 
334edb46e9SPaul Traina #include <netinet/in.h>
344edb46e9SPaul Traina #include <netinet/in_systm.h>
354edb46e9SPaul Traina #include <netinet/ip.h>
364edb46e9SPaul Traina #include <netinet/ip_var.h>
374edb46e9SPaul Traina #include <netinet/udp.h>
384edb46e9SPaul Traina #include <netinet/udp_var.h>
394edb46e9SPaul Traina 
404edb46e9SPaul Traina #include <ctype.h>
414edb46e9SPaul Traina #include <errno.h>
424edb46e9SPaul Traina #include <stdio.h>
434edb46e9SPaul Traina 
444edb46e9SPaul Traina #include "interface.h"
454edb46e9SPaul Traina #include "addrtoname.h"
464edb46e9SPaul Traina 
474edb46e9SPaul Traina const u_char *c_print(register const u_char *, register const u_char *);
484edb46e9SPaul Traina const u_char *krb4_print_hdr(const u_char *);
494edb46e9SPaul Traina void krb4_print(const u_char *);
504edb46e9SPaul Traina void krb_print(const u_char *, u_int);
514edb46e9SPaul Traina 
524edb46e9SPaul Traina 
534edb46e9SPaul Traina #define AUTH_MSG_KDC_REQUEST			1<<1
544edb46e9SPaul Traina #define AUTH_MSG_KDC_REPLY			2<<1
554edb46e9SPaul Traina #define AUTH_MSG_APPL_REQUEST			3<<1
564edb46e9SPaul Traina #define AUTH_MSG_APPL_REQUEST_MUTUAL		4<<1
574edb46e9SPaul Traina #define AUTH_MSG_ERR_REPLY			5<<1
584edb46e9SPaul Traina #define AUTH_MSG_PRIVATE			6<<1
594edb46e9SPaul Traina #define AUTH_MSG_SAFE				7<<1
604edb46e9SPaul Traina #define AUTH_MSG_APPL_ERR			8<<1
614edb46e9SPaul Traina #define AUTH_MSG_DIE				63<<1
624edb46e9SPaul Traina 
634edb46e9SPaul Traina #define KERB_ERR_OK				0
644edb46e9SPaul Traina #define KERB_ERR_NAME_EXP			1
654edb46e9SPaul Traina #define KERB_ERR_SERVICE_EXP			2
664edb46e9SPaul Traina #define KERB_ERR_AUTH_EXP			3
674edb46e9SPaul Traina #define KERB_ERR_PKT_VER			4
684edb46e9SPaul Traina #define KERB_ERR_NAME_MAST_KEY_VER		5
694edb46e9SPaul Traina #define KERB_ERR_SERV_MAST_KEY_VER		6
704edb46e9SPaul Traina #define KERB_ERR_BYTE_ORDER			7
714edb46e9SPaul Traina #define KERB_ERR_PRINCIPAL_UNKNOWN		8
724edb46e9SPaul Traina #define KERB_ERR_PRINCIPAL_NOT_UNIQUE		9
734edb46e9SPaul Traina #define KERB_ERR_NULL_KEY			10
744edb46e9SPaul Traina 
754edb46e9SPaul Traina struct krb {
764edb46e9SPaul Traina 	u_char pvno;		/* Protocol Version */
774edb46e9SPaul Traina 	u_char type;		/* Type+B */
784edb46e9SPaul Traina };
794edb46e9SPaul Traina 
804edb46e9SPaul Traina static char tstr[] = " [|kerberos]";
814edb46e9SPaul Traina 
824edb46e9SPaul Traina static struct tok type2str[] = {
834edb46e9SPaul Traina 	{ AUTH_MSG_KDC_REQUEST,		"KDC_REQUEST" },
844edb46e9SPaul Traina 	{ AUTH_MSG_KDC_REPLY,		"KDC_REPLY" },
854edb46e9SPaul Traina 	{ AUTH_MSG_APPL_REQUEST,	"APPL_REQUEST" },
864edb46e9SPaul Traina 	{ AUTH_MSG_APPL_REQUEST_MUTUAL,	"APPL_REQUEST_MUTUAL" },
874edb46e9SPaul Traina 	{ AUTH_MSG_ERR_REPLY,		"ERR_REPLY" },
884edb46e9SPaul Traina 	{ AUTH_MSG_PRIVATE,		"PRIVATE" },
894edb46e9SPaul Traina 	{ AUTH_MSG_SAFE,		"SAFE" },
904edb46e9SPaul Traina 	{ AUTH_MSG_APPL_ERR,		"APPL_ERR" },
914edb46e9SPaul Traina 	{ AUTH_MSG_DIE,			"DIE" },
924edb46e9SPaul Traina 	{ 0,				NULL }
934edb46e9SPaul Traina };
944edb46e9SPaul Traina 
954edb46e9SPaul Traina static struct tok kerr2str[] = {
964edb46e9SPaul Traina 	{ KERB_ERR_OK,			"OK" },
974edb46e9SPaul Traina 	{ KERB_ERR_NAME_EXP,		"NAME_EXP" },
984edb46e9SPaul Traina 	{ KERB_ERR_SERVICE_EXP,		"SERVICE_EXP" },
994edb46e9SPaul Traina 	{ KERB_ERR_AUTH_EXP,		"AUTH_EXP" },
1004edb46e9SPaul Traina 	{ KERB_ERR_PKT_VER,		"PKT_VER" },
1014edb46e9SPaul Traina 	{ KERB_ERR_NAME_MAST_KEY_VER,	"NAME_MAST_KEY_VER" },
1024edb46e9SPaul Traina 	{ KERB_ERR_SERV_MAST_KEY_VER,	"SERV_MAST_KEY_VER" },
1034edb46e9SPaul Traina 	{ KERB_ERR_BYTE_ORDER,		"BYTE_ORDER" },
1044edb46e9SPaul Traina 	{ KERB_ERR_PRINCIPAL_UNKNOWN,	"PRINCIPAL_UNKNOWN" },
1054edb46e9SPaul Traina 	{ KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" },
1064edb46e9SPaul Traina 	{ KERB_ERR_NULL_KEY,		"NULL_KEY"},
1074edb46e9SPaul Traina 	{ 0,				NULL}
1084edb46e9SPaul Traina };
1094edb46e9SPaul Traina 
1104edb46e9SPaul Traina 
1114edb46e9SPaul Traina /* little endian (unaligned) to host byte order */
1124edb46e9SPaul Traina /* XXX need to look at this... */
1134edb46e9SPaul Traina #define vtohlp(x)	    ((( ((char *)(x))[0] )      )  | \
1144edb46e9SPaul Traina 			     (( ((char *)(x))[1] ) <<  8)  | \
1154edb46e9SPaul Traina 			     (( ((char *)(x))[2] ) << 16)  | \
1164edb46e9SPaul Traina 			     (( ((char *)(x))[3] ) << 24))
1174edb46e9SPaul Traina #define vtohsp(x)          ((( ((char *)(x))[0] )      )  | \
1184edb46e9SPaul Traina 			     (( ((char *)(x))[1] ) <<  8))
1194edb46e9SPaul Traina /* network (big endian) (unaligned) to host byte order */
1204edb46e9SPaul Traina #define ntohlp(x)	    ((( ((char *)(x))[3] )      )  | \
1214edb46e9SPaul Traina 			     (( ((char *)(x))[2] ) <<  8)  | \
1224edb46e9SPaul Traina 			     (( ((char *)(x))[1] ) << 16)  | \
1234edb46e9SPaul Traina 			     (( ((char *)(x))[0] ) << 24))
1244edb46e9SPaul Traina #define ntohsp(x)          ((( ((char *)(x))[1] )      )  | \
1254edb46e9SPaul Traina 			     (( ((char *)(x))[0] ) <<  8))
1264edb46e9SPaul Traina 
1274edb46e9SPaul Traina 
1284edb46e9SPaul Traina 
1294edb46e9SPaul Traina const u_char *
1304edb46e9SPaul Traina c_print(register const u_char *s, register const u_char *ep)
1314edb46e9SPaul Traina {
1324edb46e9SPaul Traina 	register u_char c;
1334edb46e9SPaul Traina 	register int flag;
1344edb46e9SPaul Traina 
1354edb46e9SPaul Traina 	flag = 1;
1364644f044SBill Fenner 	while (s < ep) {
1374edb46e9SPaul Traina 		c = *s++;
1384edb46e9SPaul Traina 		if (c == '\0') {
1394edb46e9SPaul Traina 			flag = 0;
1404edb46e9SPaul Traina 			break;
1414edb46e9SPaul Traina 		}
1424edb46e9SPaul Traina 		if (!isascii(c)) {
1434edb46e9SPaul Traina 			c = toascii(c);
1444edb46e9SPaul Traina 			putchar('M');
1454edb46e9SPaul Traina 			putchar('-');
1464edb46e9SPaul Traina 		}
1474edb46e9SPaul Traina 		if (!isprint(c)) {
1484edb46e9SPaul Traina 			c ^= 0x40;	/* DEL to ?, others to alpha */
1494edb46e9SPaul Traina 			putchar('^');
1504edb46e9SPaul Traina 		}
1514edb46e9SPaul Traina 		putchar(c);
1524edb46e9SPaul Traina 	}
1534edb46e9SPaul Traina 	if (flag)
1544edb46e9SPaul Traina 		return NULL;
1554edb46e9SPaul Traina 	return (s);
1564edb46e9SPaul Traina }
1574edb46e9SPaul Traina 
1584edb46e9SPaul Traina const u_char *
1594edb46e9SPaul Traina krb4_print_hdr(const u_char *cp)
1604edb46e9SPaul Traina {
1614edb46e9SPaul Traina 	cp += 2;
1624edb46e9SPaul Traina 
1634edb46e9SPaul Traina #define PRINT		if ((cp = c_print(cp, snapend)) == NULL) goto trunc
1644edb46e9SPaul Traina 
1654edb46e9SPaul Traina 	PRINT;
1664644f044SBill Fenner 	putchar('.');
1674644f044SBill Fenner 	PRINT;
1684644f044SBill Fenner 	putchar('@');
1694644f044SBill Fenner 	PRINT;
1704edb46e9SPaul Traina 	return (cp);
1714edb46e9SPaul Traina 
1724edb46e9SPaul Traina trunc:
1734edb46e9SPaul Traina 	fputs(tstr, stdout);
1744edb46e9SPaul Traina 	return (NULL);
1754edb46e9SPaul Traina 
1764edb46e9SPaul Traina #undef PRINT
1774edb46e9SPaul Traina }
1784edb46e9SPaul Traina 
1794edb46e9SPaul Traina void
1804edb46e9SPaul Traina krb4_print(const u_char *cp)
1814edb46e9SPaul Traina {
1824edb46e9SPaul Traina 	register const struct krb *kp;
1834edb46e9SPaul Traina 	u_char type;
1844edb46e9SPaul Traina 	u_short len;
1854edb46e9SPaul Traina 
1864edb46e9SPaul Traina #define PRINT		if ((cp = c_print(cp, snapend)) == NULL) goto trunc
1874edb46e9SPaul Traina /*  True if struct krb is little endian */
1884edb46e9SPaul Traina #define IS_LENDIAN(kp)	(((kp)->type & 0x01) != 0)
1894edb46e9SPaul Traina #define KTOHSP(kp, cp)	(IS_LENDIAN(kp) ? vtohsp(cp) : ntohsp(cp))
1904edb46e9SPaul Traina 
1914edb46e9SPaul Traina 	kp = (struct krb *)cp;
1924edb46e9SPaul Traina 
1934edb46e9SPaul Traina 	if ((&kp->type) >= snapend) {
1944edb46e9SPaul Traina 		fputs(tstr, stdout);
1954edb46e9SPaul Traina 		return;
1964edb46e9SPaul Traina 	}
1974edb46e9SPaul Traina 
1984edb46e9SPaul Traina 	type = kp->type & (0xFF << 1);
1994edb46e9SPaul Traina 
2004edb46e9SPaul Traina 	printf(" %s %s: ",
2014edb46e9SPaul Traina 	    IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type));
2024edb46e9SPaul Traina 
2034edb46e9SPaul Traina 	switch (type) {
2044edb46e9SPaul Traina 
2054edb46e9SPaul Traina 	case AUTH_MSG_KDC_REQUEST:
2064edb46e9SPaul Traina 		if ((cp = krb4_print_hdr(cp)) == NULL)
2074edb46e9SPaul Traina 			return;
2084edb46e9SPaul Traina 		cp += 4;	/* ctime */
2094644f044SBill Fenner 		TCHECK(*cp);
2104edb46e9SPaul Traina 		printf(" %dmin ", *cp++ * 5);
2114edb46e9SPaul Traina 		PRINT;
2124644f044SBill Fenner 		putchar('.');
2134644f044SBill Fenner 		PRINT;
2144edb46e9SPaul Traina 		break;
2154edb46e9SPaul Traina 
2164edb46e9SPaul Traina 	case AUTH_MSG_APPL_REQUEST:
2174edb46e9SPaul Traina 		cp += 2;
2184644f044SBill Fenner 		TCHECK(*cp);
2194edb46e9SPaul Traina 		printf("v%d ", *cp++);
2204edb46e9SPaul Traina 		PRINT;
2214644f044SBill Fenner 		TCHECK(*cp);
2224edb46e9SPaul Traina 		printf(" (%d)", *cp++);
2234644f044SBill Fenner 		TCHECK(*cp);
2244edb46e9SPaul Traina 		printf(" (%d)", *cp);
2254edb46e9SPaul Traina 		break;
2264edb46e9SPaul Traina 
2274edb46e9SPaul Traina 	case AUTH_MSG_KDC_REPLY:
2284edb46e9SPaul Traina 		if ((cp = krb4_print_hdr(cp)) == NULL)
2294edb46e9SPaul Traina 			return;
2304edb46e9SPaul Traina 		cp += 10;	/* timestamp + n + exp + kvno */
2314644f044SBill Fenner 		TCHECK2(*cp, sizeof(short));
2324edb46e9SPaul Traina 		len = KTOHSP(kp, cp);
2334edb46e9SPaul Traina 		printf(" (%d)", len);
2344edb46e9SPaul Traina 		break;
2354edb46e9SPaul Traina 
2364edb46e9SPaul Traina 	case AUTH_MSG_ERR_REPLY:
2374edb46e9SPaul Traina 		if ((cp = krb4_print_hdr(cp)) == NULL)
2384edb46e9SPaul Traina 			return;
2394edb46e9SPaul Traina 		cp += 4; 	  /* timestamp */
2404644f044SBill Fenner 		TCHECK2(*cp, sizeof(short));
2414edb46e9SPaul Traina 		printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)));
2424edb46e9SPaul Traina 		cp += 4;
2434edb46e9SPaul Traina 		PRINT;
2444edb46e9SPaul Traina 		break;
2454edb46e9SPaul Traina 
2464edb46e9SPaul Traina 	default:
2474edb46e9SPaul Traina 		fputs("(unknown)", stdout);
2484edb46e9SPaul Traina 		break;
2494edb46e9SPaul Traina 	}
2504edb46e9SPaul Traina 
2514edb46e9SPaul Traina 	return;
2524edb46e9SPaul Traina trunc:
2534edb46e9SPaul Traina 	fputs(tstr, stdout);
2544edb46e9SPaul Traina }
2554edb46e9SPaul Traina 
2564edb46e9SPaul Traina void
2574edb46e9SPaul Traina krb_print(const u_char *dat, u_int length)
2584edb46e9SPaul Traina {
2594edb46e9SPaul Traina 	register const struct krb *kp;
2604edb46e9SPaul Traina 
2614edb46e9SPaul Traina 	kp = (struct krb *)dat;
2624edb46e9SPaul Traina 
2634edb46e9SPaul Traina 	if (dat >= snapend) {
2644edb46e9SPaul Traina 		fputs(tstr, stdout);
2654edb46e9SPaul Traina 		return;
2664edb46e9SPaul Traina 	}
2674edb46e9SPaul Traina 
2684edb46e9SPaul Traina 	switch (kp->pvno) {
2694edb46e9SPaul Traina 
2704edb46e9SPaul Traina 	case 1:
2714edb46e9SPaul Traina 	case 2:
2724edb46e9SPaul Traina 	case 3:
2734edb46e9SPaul Traina 		printf(" v%d", kp->pvno);
2744edb46e9SPaul Traina 		break;
2754edb46e9SPaul Traina 
2764edb46e9SPaul Traina 	case 4:
2774edb46e9SPaul Traina 		printf(" v%d", kp->pvno);
2784edb46e9SPaul Traina 		krb4_print((const u_char *)kp);
2794edb46e9SPaul Traina 		break;
2804edb46e9SPaul Traina 
2814edb46e9SPaul Traina 	case 106:
2824edb46e9SPaul Traina 	case 107:
2834edb46e9SPaul Traina 		fputs(" v5", stdout);
2844edb46e9SPaul Traina 		/* Decode ASN.1 here "someday" */
2854edb46e9SPaul Traina 		break;
2864edb46e9SPaul Traina 	}
2874edb46e9SPaul Traina 	return;
2884edb46e9SPaul Traina }
289