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 24*3c602fabSXin LI #define NETDISSECT_REWORKED 25b0453382SBill Fenner #ifdef HAVE_CONFIG_H 26b0453382SBill Fenner #include "config.h" 274edb46e9SPaul Traina #endif 284edb46e9SPaul Traina 295b0fe478SBruce M Simpson #include <tcpdump-stdinc.h> 304edb46e9SPaul Traina 314edb46e9SPaul Traina #include "interface.h" 325b0fe478SBruce M Simpson #include "extract.h" 334edb46e9SPaul Traina 34*3c602fabSXin LI static const char tstr[] = " [|kerberos]"; 35*3c602fabSXin LI 36*3c602fabSXin LI static const u_char *c_print(netdissect_options *, register const u_char *, register const u_char *); 37*3c602fabSXin LI static const u_char *krb4_print_hdr(netdissect_options *, const u_char *); 38*3c602fabSXin LI static void krb4_print(netdissect_options *, const u_char *); 394edb46e9SPaul Traina 404edb46e9SPaul Traina #define AUTH_MSG_KDC_REQUEST 1<<1 414edb46e9SPaul Traina #define AUTH_MSG_KDC_REPLY 2<<1 424edb46e9SPaul Traina #define AUTH_MSG_APPL_REQUEST 3<<1 434edb46e9SPaul Traina #define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 444edb46e9SPaul Traina #define AUTH_MSG_ERR_REPLY 5<<1 454edb46e9SPaul Traina #define AUTH_MSG_PRIVATE 6<<1 464edb46e9SPaul Traina #define AUTH_MSG_SAFE 7<<1 474edb46e9SPaul Traina #define AUTH_MSG_APPL_ERR 8<<1 484edb46e9SPaul Traina #define AUTH_MSG_DIE 63<<1 494edb46e9SPaul Traina 504edb46e9SPaul Traina #define KERB_ERR_OK 0 514edb46e9SPaul Traina #define KERB_ERR_NAME_EXP 1 524edb46e9SPaul Traina #define KERB_ERR_SERVICE_EXP 2 534edb46e9SPaul Traina #define KERB_ERR_AUTH_EXP 3 544edb46e9SPaul Traina #define KERB_ERR_PKT_VER 4 554edb46e9SPaul Traina #define KERB_ERR_NAME_MAST_KEY_VER 5 564edb46e9SPaul Traina #define KERB_ERR_SERV_MAST_KEY_VER 6 574edb46e9SPaul Traina #define KERB_ERR_BYTE_ORDER 7 584edb46e9SPaul Traina #define KERB_ERR_PRINCIPAL_UNKNOWN 8 594edb46e9SPaul Traina #define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 604edb46e9SPaul Traina #define KERB_ERR_NULL_KEY 10 614edb46e9SPaul Traina 624edb46e9SPaul Traina struct krb { 63*3c602fabSXin LI uint8_t pvno; /* Protocol Version */ 64*3c602fabSXin LI uint8_t type; /* Type+B */ 654edb46e9SPaul Traina }; 664edb46e9SPaul Traina 67*3c602fabSXin LI static const struct tok type2str[] = { 684edb46e9SPaul Traina { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" }, 694edb46e9SPaul Traina { AUTH_MSG_KDC_REPLY, "KDC_REPLY" }, 704edb46e9SPaul Traina { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" }, 714edb46e9SPaul Traina { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" }, 724edb46e9SPaul Traina { AUTH_MSG_ERR_REPLY, "ERR_REPLY" }, 734edb46e9SPaul Traina { AUTH_MSG_PRIVATE, "PRIVATE" }, 744edb46e9SPaul Traina { AUTH_MSG_SAFE, "SAFE" }, 754edb46e9SPaul Traina { AUTH_MSG_APPL_ERR, "APPL_ERR" }, 764edb46e9SPaul Traina { AUTH_MSG_DIE, "DIE" }, 774edb46e9SPaul Traina { 0, NULL } 784edb46e9SPaul Traina }; 794edb46e9SPaul Traina 80*3c602fabSXin LI static const struct tok kerr2str[] = { 814edb46e9SPaul Traina { KERB_ERR_OK, "OK" }, 824edb46e9SPaul Traina { KERB_ERR_NAME_EXP, "NAME_EXP" }, 834edb46e9SPaul Traina { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" }, 844edb46e9SPaul Traina { KERB_ERR_AUTH_EXP, "AUTH_EXP" }, 854edb46e9SPaul Traina { KERB_ERR_PKT_VER, "PKT_VER" }, 864edb46e9SPaul Traina { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" }, 874edb46e9SPaul Traina { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" }, 884edb46e9SPaul Traina { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" }, 894edb46e9SPaul Traina { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" }, 904edb46e9SPaul Traina { KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" }, 914edb46e9SPaul Traina { KERB_ERR_NULL_KEY, "NULL_KEY"}, 924edb46e9SPaul Traina { 0, NULL} 934edb46e9SPaul Traina }; 944edb46e9SPaul Traina 955b0fe478SBruce M Simpson static const u_char * 96*3c602fabSXin LI c_print(netdissect_options *ndo, 97*3c602fabSXin LI register const u_char *s, register const u_char *ep) 984edb46e9SPaul Traina { 994edb46e9SPaul Traina register u_char c; 1004edb46e9SPaul Traina register int flag; 1014edb46e9SPaul Traina 1024edb46e9SPaul Traina flag = 1; 1034644f044SBill Fenner while (s < ep) { 1044edb46e9SPaul Traina c = *s++; 1054edb46e9SPaul Traina if (c == '\0') { 1064edb46e9SPaul Traina flag = 0; 1074edb46e9SPaul Traina break; 1084edb46e9SPaul Traina } 109*3c602fabSXin LI if (!ND_ISASCII(c)) { 110*3c602fabSXin LI c = ND_TOASCII(c); 111*3c602fabSXin LI ND_PRINT((ndo, "M-")); 1124edb46e9SPaul Traina } 113*3c602fabSXin LI if (!ND_ISPRINT(c)) { 1144edb46e9SPaul Traina c ^= 0x40; /* DEL to ?, others to alpha */ 115*3c602fabSXin LI ND_PRINT((ndo, "^")); 1164edb46e9SPaul Traina } 117*3c602fabSXin LI ND_PRINT((ndo, "%c", c)); 1184edb46e9SPaul Traina } 1194edb46e9SPaul Traina if (flag) 1204edb46e9SPaul Traina return NULL; 1214edb46e9SPaul Traina return (s); 1224edb46e9SPaul Traina } 1234edb46e9SPaul Traina 1245b0fe478SBruce M Simpson static const u_char * 125*3c602fabSXin LI krb4_print_hdr(netdissect_options *ndo, 126*3c602fabSXin LI const u_char *cp) 1274edb46e9SPaul Traina { 1284edb46e9SPaul Traina cp += 2; 1294edb46e9SPaul Traina 130*3c602fabSXin LI #define PRINT if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc 1314edb46e9SPaul Traina 1324edb46e9SPaul Traina PRINT; 133*3c602fabSXin LI ND_PRINT((ndo, ".")); 1344644f044SBill Fenner PRINT; 135*3c602fabSXin LI ND_PRINT((ndo, "@")); 1364644f044SBill Fenner PRINT; 1374edb46e9SPaul Traina return (cp); 1384edb46e9SPaul Traina 1394edb46e9SPaul Traina trunc: 140*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1414edb46e9SPaul Traina return (NULL); 1424edb46e9SPaul Traina 1434edb46e9SPaul Traina #undef PRINT 1444edb46e9SPaul Traina } 1454edb46e9SPaul Traina 1465b0fe478SBruce M Simpson static void 147*3c602fabSXin LI krb4_print(netdissect_options *ndo, 148*3c602fabSXin LI const u_char *cp) 1494edb46e9SPaul Traina { 1504edb46e9SPaul Traina register const struct krb *kp; 1514edb46e9SPaul Traina u_char type; 1524edb46e9SPaul Traina u_short len; 1534edb46e9SPaul Traina 154*3c602fabSXin LI #define PRINT if ((cp = c_print(ndo, cp, ndo->ndo_snapend)) == NULL) goto trunc 1554edb46e9SPaul Traina /* True if struct krb is little endian */ 1564edb46e9SPaul Traina #define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) 1575b0fe478SBruce M Simpson #define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) 1584edb46e9SPaul Traina 1594edb46e9SPaul Traina kp = (struct krb *)cp; 1604edb46e9SPaul Traina 161*3c602fabSXin LI if ((&kp->type) >= ndo->ndo_snapend) { 162*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1634edb46e9SPaul Traina return; 1644edb46e9SPaul Traina } 1654edb46e9SPaul Traina 1664edb46e9SPaul Traina type = kp->type & (0xFF << 1); 1674edb46e9SPaul Traina 168*3c602fabSXin LI ND_PRINT((ndo, " %s %s: ", 169*3c602fabSXin LI IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type))); 1704edb46e9SPaul Traina 1714edb46e9SPaul Traina switch (type) { 1724edb46e9SPaul Traina 1734edb46e9SPaul Traina case AUTH_MSG_KDC_REQUEST: 174*3c602fabSXin LI if ((cp = krb4_print_hdr(ndo, cp)) == NULL) 1754edb46e9SPaul Traina return; 1764edb46e9SPaul Traina cp += 4; /* ctime */ 177*3c602fabSXin LI ND_TCHECK(*cp); 178*3c602fabSXin LI ND_PRINT((ndo, " %dmin ", *cp++ * 5)); 1794edb46e9SPaul Traina PRINT; 180*3c602fabSXin LI ND_PRINT((ndo, ".")); 1814644f044SBill Fenner PRINT; 1824edb46e9SPaul Traina break; 1834edb46e9SPaul Traina 1844edb46e9SPaul Traina case AUTH_MSG_APPL_REQUEST: 1854edb46e9SPaul Traina cp += 2; 186*3c602fabSXin LI ND_TCHECK(*cp); 187*3c602fabSXin LI ND_PRINT((ndo, "v%d ", *cp++)); 1884edb46e9SPaul Traina PRINT; 189*3c602fabSXin LI ND_TCHECK(*cp); 190*3c602fabSXin LI ND_PRINT((ndo, " (%d)", *cp++)); 191*3c602fabSXin LI ND_TCHECK(*cp); 192*3c602fabSXin LI ND_PRINT((ndo, " (%d)", *cp)); 1934edb46e9SPaul Traina break; 1944edb46e9SPaul Traina 1954edb46e9SPaul Traina case AUTH_MSG_KDC_REPLY: 196*3c602fabSXin LI if ((cp = krb4_print_hdr(ndo, cp)) == NULL) 1974edb46e9SPaul Traina return; 1984edb46e9SPaul Traina cp += 10; /* timestamp + n + exp + kvno */ 199*3c602fabSXin LI ND_TCHECK2(*cp, sizeof(short)); 2004edb46e9SPaul Traina len = KTOHSP(kp, cp); 201*3c602fabSXin LI ND_PRINT((ndo, " (%d)", len)); 2024edb46e9SPaul Traina break; 2034edb46e9SPaul Traina 2044edb46e9SPaul Traina case AUTH_MSG_ERR_REPLY: 205*3c602fabSXin LI if ((cp = krb4_print_hdr(ndo, cp)) == NULL) 2064edb46e9SPaul Traina return; 2074edb46e9SPaul Traina cp += 4; /* timestamp */ 208*3c602fabSXin LI ND_TCHECK2(*cp, sizeof(short)); 209*3c602fabSXin LI ND_PRINT((ndo, " %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)))); 2104edb46e9SPaul Traina cp += 4; 2114edb46e9SPaul Traina PRINT; 2124edb46e9SPaul Traina break; 2134edb46e9SPaul Traina 2144edb46e9SPaul Traina default: 215*3c602fabSXin LI ND_PRINT((ndo, "(unknown)")); 2164edb46e9SPaul Traina break; 2174edb46e9SPaul Traina } 2184edb46e9SPaul Traina 2194edb46e9SPaul Traina return; 2204edb46e9SPaul Traina trunc: 221*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2224edb46e9SPaul Traina } 2234edb46e9SPaul Traina 2244edb46e9SPaul Traina void 225*3c602fabSXin LI krb_print(netdissect_options *ndo, 226*3c602fabSXin LI const u_char *dat) 2274edb46e9SPaul Traina { 2284edb46e9SPaul Traina register const struct krb *kp; 2294edb46e9SPaul Traina 2304edb46e9SPaul Traina kp = (struct krb *)dat; 2314edb46e9SPaul Traina 232*3c602fabSXin LI if (dat >= ndo->ndo_snapend) { 233*3c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2344edb46e9SPaul Traina return; 2354edb46e9SPaul Traina } 2364edb46e9SPaul Traina 2374edb46e9SPaul Traina switch (kp->pvno) { 2384edb46e9SPaul Traina 2394edb46e9SPaul Traina case 1: 2404edb46e9SPaul Traina case 2: 2414edb46e9SPaul Traina case 3: 242*3c602fabSXin LI ND_PRINT((ndo, " v%d", kp->pvno)); 2434edb46e9SPaul Traina break; 2444edb46e9SPaul Traina 2454edb46e9SPaul Traina case 4: 246*3c602fabSXin LI ND_PRINT((ndo, " v%d", kp->pvno)); 247*3c602fabSXin LI krb4_print(ndo, (const u_char *)kp); 2484edb46e9SPaul Traina break; 2494edb46e9SPaul Traina 2504edb46e9SPaul Traina case 106: 2514edb46e9SPaul Traina case 107: 252*3c602fabSXin LI ND_PRINT((ndo, " v5")); 2534edb46e9SPaul Traina /* Decode ASN.1 here "someday" */ 2544edb46e9SPaul Traina break; 2554edb46e9SPaul Traina } 2564edb46e9SPaul Traina return; 2574edb46e9SPaul Traina } 258