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