1/* 2 * Copyright (c) 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Initial contribution from John Hawkinson (jhawk@mit.edu). 22 */ 23 24#include <sys/cdefs.h> 25#ifndef lint 26#if 0 27static const char rcsid[] _U_ = 28 "@(#) Header: /tcpdump/master/tcpdump/print-krb.c,v 1.23 2003-11-16 09:36:26 guy Exp"; 29#else 30__RCSID("$NetBSD: print-krb.c,v 1.2 2010/12/05 05:11:30 christos Exp $"); 31#endif 32#endif 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <tcpdump-stdinc.h> 39 40#include <stdio.h> 41 42#include "interface.h" 43#include "addrtoname.h" 44#include "extract.h" 45 46static const u_char *c_print(register const u_char *, register const u_char *); 47static const u_char *krb4_print_hdr(const u_char *); 48static void krb4_print(const u_char *); 49 50#define AUTH_MSG_KDC_REQUEST 1<<1 51#define AUTH_MSG_KDC_REPLY 2<<1 52#define AUTH_MSG_APPL_REQUEST 3<<1 53#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1 54#define AUTH_MSG_ERR_REPLY 5<<1 55#define AUTH_MSG_PRIVATE 6<<1 56#define AUTH_MSG_SAFE 7<<1 57#define AUTH_MSG_APPL_ERR 8<<1 58#define AUTH_MSG_DIE 63<<1 59 60#define KERB_ERR_OK 0 61#define KERB_ERR_NAME_EXP 1 62#define KERB_ERR_SERVICE_EXP 2 63#define KERB_ERR_AUTH_EXP 3 64#define KERB_ERR_PKT_VER 4 65#define KERB_ERR_NAME_MAST_KEY_VER 5 66#define KERB_ERR_SERV_MAST_KEY_VER 6 67#define KERB_ERR_BYTE_ORDER 7 68#define KERB_ERR_PRINCIPAL_UNKNOWN 8 69#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9 70#define KERB_ERR_NULL_KEY 10 71 72struct krb { 73 u_int8_t pvno; /* Protocol Version */ 74 u_int8_t type; /* Type+B */ 75}; 76 77static char tstr[] = " [|kerberos]"; 78 79static struct tok type2str[] = { 80 { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" }, 81 { AUTH_MSG_KDC_REPLY, "KDC_REPLY" }, 82 { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" }, 83 { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" }, 84 { AUTH_MSG_ERR_REPLY, "ERR_REPLY" }, 85 { AUTH_MSG_PRIVATE, "PRIVATE" }, 86 { AUTH_MSG_SAFE, "SAFE" }, 87 { AUTH_MSG_APPL_ERR, "APPL_ERR" }, 88 { AUTH_MSG_DIE, "DIE" }, 89 { 0, NULL } 90}; 91 92static struct tok kerr2str[] = { 93 { KERB_ERR_OK, "OK" }, 94 { KERB_ERR_NAME_EXP, "NAME_EXP" }, 95 { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" }, 96 { KERB_ERR_AUTH_EXP, "AUTH_EXP" }, 97 { KERB_ERR_PKT_VER, "PKT_VER" }, 98 { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" }, 99 { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" }, 100 { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" }, 101 { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" }, 102 { KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" }, 103 { KERB_ERR_NULL_KEY, "NULL_KEY"}, 104 { 0, NULL} 105}; 106 107static const u_char * 108c_print(register const u_char *s, register const u_char *ep) 109{ 110 register u_char c; 111 register int flag; 112 113 flag = 1; 114 while (s < ep) { 115 c = *s++; 116 if (c == '\0') { 117 flag = 0; 118 break; 119 } 120 if (!isascii(c)) { 121 c = toascii(c); 122 putchar('M'); 123 putchar('-'); 124 } 125 if (!isprint(c)) { 126 c ^= 0x40; /* DEL to ?, others to alpha */ 127 putchar('^'); 128 } 129 putchar(c); 130 } 131 if (flag) 132 return NULL; 133 return (s); 134} 135 136static const u_char * 137krb4_print_hdr(const u_char *cp) 138{ 139 cp += 2; 140 141#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc 142 143 PRINT; 144 putchar('.'); 145 PRINT; 146 putchar('@'); 147 PRINT; 148 return (cp); 149 150trunc: 151 fputs(tstr, stdout); 152 return (NULL); 153 154#undef PRINT 155} 156 157static void 158krb4_print(const u_char *cp) 159{ 160 register const struct krb *kp; 161 u_char type; 162 u_short len; 163 164#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc 165/* True if struct krb is little endian */ 166#define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0) 167#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp)) 168 169 kp = (struct krb *)cp; 170 171 if ((&kp->type) >= snapend) { 172 fputs(tstr, stdout); 173 return; 174 } 175 176 type = kp->type & (0xFF << 1); 177 178 printf(" %s %s: ", 179 IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type)); 180 181 switch (type) { 182 183 case AUTH_MSG_KDC_REQUEST: 184 if ((cp = krb4_print_hdr(cp)) == NULL) 185 return; 186 cp += 4; /* ctime */ 187 TCHECK(*cp); 188 printf(" %dmin ", *cp++ * 5); 189 PRINT; 190 putchar('.'); 191 PRINT; 192 break; 193 194 case AUTH_MSG_APPL_REQUEST: 195 cp += 2; 196 TCHECK(*cp); 197 printf("v%d ", *cp++); 198 PRINT; 199 TCHECK(*cp); 200 printf(" (%d)", *cp++); 201 TCHECK(*cp); 202 printf(" (%d)", *cp); 203 break; 204 205 case AUTH_MSG_KDC_REPLY: 206 if ((cp = krb4_print_hdr(cp)) == NULL) 207 return; 208 cp += 10; /* timestamp + n + exp + kvno */ 209 TCHECK2(*cp, sizeof(short)); 210 len = KTOHSP(kp, cp); 211 printf(" (%d)", len); 212 break; 213 214 case AUTH_MSG_ERR_REPLY: 215 if ((cp = krb4_print_hdr(cp)) == NULL) 216 return; 217 cp += 4; /* timestamp */ 218 TCHECK2(*cp, sizeof(short)); 219 printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp))); 220 cp += 4; 221 PRINT; 222 break; 223 224 default: 225 fputs("(unknown)", stdout); 226 break; 227 } 228 229 return; 230trunc: 231 fputs(tstr, stdout); 232} 233 234void 235krb_print(const u_char *dat) 236{ 237 register const struct krb *kp; 238 239 kp = (struct krb *)dat; 240 241 if (dat >= snapend) { 242 fputs(tstr, stdout); 243 return; 244 } 245 246 switch (kp->pvno) { 247 248 case 1: 249 case 2: 250 case 3: 251 printf(" v%d", kp->pvno); 252 break; 253 254 case 4: 255 printf(" v%d", kp->pvno); 256 krb4_print((const u_char *)kp); 257 break; 258 259 case 106: 260 case 107: 261 fputs(" v5", stdout); 262 /* Decode ASN.1 here "someday" */ 263 break; 264 } 265 return; 266} 267