[5711] in Kerberos
tcpdump 3.0 patches for kerberos 4
daemon@ATHENA.MIT.EDU (John Hawkinson)
Wed Aug 16 02:00:33 1995
Date: Wed, 16 Aug 95 01:46:22 -0400
To: tcpdump@ee.lbl.gov, kerberos@MIT.EDU
From: John Hawkinson <jhawk@MIT.EDU>
Attached are patches to tcpdump 3.0.2 to support decoding of kerberos
4. Of course, nice things like tickets are encrypted :-), but there's
still plenty of useful information.
I've tested this under NetBSD-current/i386, Solaris 2.3, and IRIX 5.2;
I'm sure it'll work fine on other platforms.
This code of course doesn't support k5. Perhaps if I'm feeling bored
I'll abstract the ASN.1 stuff from print-snmp.c and do something with it.
Kerberos people, tcpdump is available from ftp.ee.lbl.gov.
--jhawk@mit.edu
John Hawkinson
*** print-udp.c.orig Wed Aug 16 01:35:00 1995
--- print-udp.c Wed Aug 16 01:35:10 1995
***************
*** 127,137 ****
--- 127,139 ----
/* XXX probably should use getservbyname() and cache answers */
#define TFTP_PORT 69 /*XXX*/
+ #define KERBEROS_PORT 88 /*XXX*/
#define SUNRPC_PORT 111 /*XXX*/
#define SNMP_PORT 161 /*XXX*/
#define NTP_PORT 123 /*XXX*/
#define SNMPTRAP_PORT 162 /*XXX*/
#define RIP_PORT 520 /*XXX*/
+ #define KERBEROS-SEC_PORT 750 /*XXX*/
void
udp_print(register const u_char *bp, int length, register const u_char *bp2)
***************
*** 247,252 ****
--- 249,256 ----
snmp_print((const u_char *)(up + 1), length);
else if (ISPORT(NTP_PORT))
ntp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS-SEC_PORT))
+ krb_print((const void*)(up + 1), length);
else if (dport == 3456)
vat_print((const void *)(up + 1), length, up);
/*
*** /dev/null Tue Aug 15 23:20:57 1995
--- print-krb.c Wed Aug 16 01:33:28 1995
***************
*** 0 ****
--- 1,288 ----
+ /*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+ #ifndef lint
+ static char rcsid[] =
+ "@(#) $Header: /afs/sipb/project/tcpdump/src/tcpdump-3.0.2/RCS/print-krb.c,v 1.3 1995/08/16 05:33:27 jhawk Exp $";
+ #endif
+
+ #include <sys/param.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+
+ #include <netinet/in.h>
+ #include <netinet/in_systm.h>
+ #include <netinet/ip.h>
+ #include <netinet/ip_var.h>
+ #include <netinet/udp.h>
+ #include <netinet/udp_var.h>
+
+ #include <ctype.h>
+ #include <errno.h>
+ #include <stdio.h>
+
+ #include "interface.h"
+ #include "addrtoname.h"
+
+ const char *c_print(register const u_char *s, register const u_char *ep);
+ const u_char *krb4_print_hdr(const u_char *cp);
+ void krb4_print(const u_char *cp);
+ void krb_print(const u_char *dat, int length);
+
+
+ #define AUTH_MSG_KDC_REQUEST 1<<1
+ #define AUTH_MSG_KDC_REPLY 2<<1
+ #define AUTH_MSG_APPL_REQUEST 3<<1
+ #define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1
+ #define AUTH_MSG_ERR_REPLY 5<<1
+ #define AUTH_MSG_PRIVATE 6<<1
+ #define AUTH_MSG_SAFE 7<<1
+ #define AUTH_MSG_APPL_ERR 8<<1
+ #define AUTH_MSG_DIE 63<<1
+
+ #define KERB_ERR_OK 0
+ #define KERB_ERR_NAME_EXP 1
+ #define KERB_ERR_SERVICE_EXP 2
+ #define KERB_ERR_AUTH_EXP 3
+ #define KERB_ERR_PKT_VER 4
+ #define KERB_ERR_NAME_MAST_KEY_VER 5
+ #define KERB_ERR_SERV_MAST_KEY_VER 6
+ #define KERB_ERR_BYTE_ORDER 7
+ #define KERB_ERR_PRINCIPAL_UNKNOWN 8
+ #define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
+ #define KERB_ERR_NULL_KEY 10
+
+ struct krb {
+ u_char pvno; /* Protocol Version */
+ u_char type; /* Type+B */
+ } ;
+
+ static char tstr[] = " [|kerberos]";
+
+ static struct token type2str[] = {
+ { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" },
+ { AUTH_MSG_KDC_REPLY, "KDC_REPLY" },
+ { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" },
+ { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" },
+ { AUTH_MSG_ERR_REPLY, "ERR_REPLY" },
+ { AUTH_MSG_PRIVATE, "PRIVATE" },
+ { AUTH_MSG_SAFE, "SAFE" },
+ { AUTH_MSG_APPL_ERR, "APPL_ERR" },
+ { AUTH_MSG_DIE, "DIE" },
+ { 0, NULL }
+ };
+
+ static struct token kerr2str[] = {
+ { KERB_ERR_OK, "OK" },
+ { KERB_ERR_NAME_EXP, "NAME_EXP" },
+ { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" },
+ { KERB_ERR_AUTH_EXP, "AUTH_EXP" },
+ { KERB_ERR_PKT_VER, "PKT_VER" },
+ { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" },
+ { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" },
+ { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" },
+ { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" },
+ { KERB_ERR_PRINCIPAL_NOT_UNIQUE, "PRINCIPAL_NOT_UNIQUE" },
+ { KERB_ERR_NULL_KEY, "NULL_KEY"},
+ { 0, NULL}
+ };
+
+
+ /* little endian (unaligned) to host byte order */
+ #define vtohlp(x) ((( ((char*)(x))[0] ) ) | \
+ (( ((char*)(x))[1] ) << 8) | \
+ (( ((char*)(x))[2] ) << 16) | \
+ (( ((char*)(x))[3] ) << 24))
+ #define vtohsp(x) ((( ((char*)(x))[0] ) ) | \
+ (( ((char*)(x))[1] ) << 8))
+ /* network (big endian) (unaligned) to host byte order */
+ #define ntohlp(x) ((( ((char*)(x))[3] ) ) | \
+ (( ((char*)(x))[2] ) << 8) | \
+ (( ((char*)(x))[1] ) << 16) | \
+ (( ((char*)(x))[0] ) << 24))
+ #define ntohsp(x) ((( ((char*)(x))[1] ) ) | \
+ (( ((char*)(x))[0] ) << 8))
+
+
+
+ const char *
+ c_print(register const u_char *s, register const u_char *ep)
+ {
+ register u_char c;
+ register int flag;
+
+ flag = 1;
+ while (ep == NULL || s < ep) {
+ c = *s++;
+ if (c == '\0') {
+ flag = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ if (flag)
+ return NULL;
+ return(s);
+ }
+
+
+ const u_char *
+ krb4_print_hdr(const u_char *cp)
+ {
+ cp+=2;
+
+ #define TCHECK if (cp >= snapend) goto trunc
+ #define PRINT if ((cp=c_print(cp, snapend))==NULL) goto trunc
+
+ TCHECK;
+ PRINT;
+ TCHECK;
+ putchar('.'); PRINT;
+ TCHECK;
+ putchar('@'); PRINT;
+ return(cp);
+
+ trunc:
+ fputs(tstr, stdout);
+ return(NULL);
+
+ #undef TCHECK
+ #undef PRINT
+ }
+
+ void krb4_print(const u_char *cp)
+ {
+ register const struct krb *kp;
+ u_char type;
+ u_short len;
+
+ #define TCHECK if (cp >= snapend) goto trunc
+ #define PRINT if ((cp=c_print(cp, snapend))==NULL) goto trunc
+ #define ENDIAN (kp->type & 0x01)
+ /* ENDIAN is 1 for little, 0 for big */
+
+ kp = (struct krb *)cp;
+
+ if ((&kp->type) >= snapend) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ type = kp->type & (0xFF << 1);
+
+ printf(" %s %s: ", ENDIAN?"le":"be", tok2str(type2str, NULL, type));
+
+ switch(type) {
+ case AUTH_MSG_KDC_REQUEST:
+ if ((cp=krb4_print_hdr(cp)) == NULL)
+ return;
+ cp+=4; /* ctime */
+ TCHECK;
+ printf(" %dmin ", *cp++ * 5);
+ TCHECK;
+ PRINT;
+ TCHECK;
+ putchar('.'); PRINT;
+ break;
+ case AUTH_MSG_APPL_REQUEST:
+ cp+=2;
+ TCHECK;
+ printf("v%d ", *cp++);
+ TCHECK;
+ PRINT;
+ TCHECK;
+ printf(" (%d)", *cp++);
+ TCHECK;
+ printf(" (%d)", *cp);
+ TCHECK;
+ break;
+ case AUTH_MSG_KDC_REPLY:
+ if ((cp=krb4_print_hdr(cp)) == NULL)
+ return;
+ cp+=10; /* timestamp + n + exp + kvno */
+ TCHECK;
+ len=ENDIAN? vtohsp(cp) : ntohsp(cp);
+ printf(" (%d)", len);
+ TCHECK;
+ break;
+ case AUTH_MSG_ERR_REPLY:
+ if ((cp=krb4_print_hdr(cp)) == NULL)
+ return;
+ cp+=4; /* timestamp */
+ TCHECK;
+ printf(" %s ", tok2str(kerr2str, NULL,
+ ENDIAN? vtohlp(cp) :
+ ntohlp(cp)
+ ));
+ cp+=4;
+ TCHECK;
+ PRINT;
+ break;
+ default:
+ fputs("(unknown)", stdout);
+ break;
+ }
+
+ return;
+ trunc:
+ fputs(tstr, stdout);
+ #undef TCHECK
+ }
+
+ void
+ krb_print(const u_char *dat, int length)
+ {
+ register const struct krb *kp;
+
+ kp = (struct krb *)dat;
+
+ if (dat >= snapend) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ switch (kp->pvno) {
+ case 1:
+ case 2:
+ case 3:
+ printf(" v%d", kp->pvno);
+ case 4:
+ printf(" v%d", kp->pvno);
+ krb4_print((const u_char*)kp);
+ break;
+ case 106:
+ case 107:
+ fputs(" v5", stdout);
+ /* Decode ASN.1 here "someday" */
+ break;
+ }
+ return;
+ }