2 * Routines for Kerberos
3 * Wes Hardaker (c) 2000
4 * wjhardaker@ucdavis.edu
5 * Richard Sharpe (C) 2002, rsharpe@samba.org, modularized a bit more and
6 * added AP-REQ and AP-REP dissection
8 * See RFC 1510, and various I-Ds and other documents showing additions,
9 * e.g. ones listed under
11 * http://www.isi.edu/people/bcn/krb-revisions/
13 * $Id: packet-kerberos.c,v 1.36 2002/09/10 08:55:34 guy Exp $
15 * Ethereal - Network traffic analyzer
16 * By Gerald Combs <gerald@ethereal.com>
17 * Copyright 1998 Gerald Combs
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 #include <epan/packet.h>
46 #include <epan/strutil.h>
49 #include "packet-netbios.h"
50 #include "packet-gssapi.h"
52 #define UDP_PORT_KERBEROS 88
53 #define TCP_PORT_KERBEROS 88
55 static gint proto_kerberos = -1;
57 static gint ett_kerberos = -1;
58 static gint ett_preauth = -1;
59 static gint ett_addresses = -1;
60 static gint ett_request = -1;
61 static gint ett_princ = -1;
62 static gint ett_ticket = -1;
63 static gint ett_encrypted = -1;
64 static gint ett_etype = -1;
65 static gint ett_additional_tickets = -1;
67 #define KRB5_MSG_AS_REQ 10 /* AS-REQ type */
68 #define KRB5_MSG_AS_REP 11 /* AS-REP type */
69 #define KRB5_MSG_TGS_REQ 12 /* TGS-REQ type */
70 #define KRB5_MSG_TGS_REP 13 /* TGS-REP type */
71 #define KRB5_MSG_AP_REQ 14 /* AP-REQ type */
72 #define KRB5_MSG_AP_REP 15 /* AP-REP type */
74 #define KRB5_MSG_SAFE 20 /* KRB-SAFE type */
75 #define KRB5_MSG_PRIV 21 /* KRB-PRIV type */
76 #define KRB5_MSG_CRED 22 /* KRB-CRED type */
77 #define KRB5_MSG_ERROR 30 /* KRB-ERROR type */
79 /* Type tags within KDC-REQ */
80 #define KRB5_KDC_REQ_PVNO 1
81 #define KRB5_KDC_REQ_MSG_TYPE 2
82 #define KRB5_KDC_REQ_PADATA 3
83 #define KRB5_KDC_REQ_REQBODY 4
85 /* Type tags within KDC-REP */
86 #define KRB5_KDC_REP_PVNO 0
87 #define KRB5_KDC_REP_MSG_TYPE 1
88 #define KRB5_KDC_REP_PADATA 2
89 #define KRB5_KDC_REP_CREALM 3
90 #define KRB5_KDC_REP_CNAME 4
91 #define KRB5_KDC_REP_TICKET 5
92 #define KRB5_KDC_REP_ENC_PART 6
94 /* Type tags within KDC-REQ-BODY */
95 #define KRB5_BODY_KDC_OPTIONS 0
96 #define KRB5_BODY_CNAME 1
97 #define KRB5_BODY_REALM 2
98 #define KRB5_BODY_SNAME 3
99 #define KRB5_BODY_FROM 4
100 #define KRB5_BODY_TILL 5
101 #define KRB5_BODY_RTIME 6
102 #define KRB5_BODY_NONCE 7
103 #define KRB5_BODY_ENCTYPE 8
104 #define KRB5_BODY_ADDRESSES 9
105 #define KRB5_BODY_ENC_AUTHORIZATION_DATA 10
106 #define KRB5_BODY_ADDITIONAL_TICKETS 11
108 /* TAGs within AP-REQ */
109 #define KRB5_AP_REQ_APOPTIONS 2
110 #define KRB5_AP_REQ_TICKET 3
111 #define KRB5_AP_REQ_ENC_DATA 4
113 /* TAGs within AP-REP */
114 #define KRB5_AP_REP_ENC_DATA 2
116 /* Type tags within KRB-ERROR */
117 #define KRB5_ERROR_PVNO 0
118 #define KRB5_ERROR_MSG_TYPE 1
119 #define KRB5_ERROR_CTIME 2
120 #define KRB5_ERROR_CUSEC 3
121 #define KRB5_ERROR_STIME 4
122 #define KRB5_ERROR_SUSEC 5
123 #define KRB5_ERROR_ERROR_CODE 6
124 #define KRB5_ERROR_CREALM 7
125 #define KRB5_ERROR_CNAME 8
126 #define KRB5_ERROR_REALM 9
127 #define KRB5_ERROR_SNAME 10
128 #define KRB5_ERROR_ETEXT 11
129 #define KRB5_ERROR_EDATA 12
131 /* address type constants */
132 #define KRB5_ADDR_IPv4 0x02
133 #define KRB5_ADDR_CHAOS 0x05
134 #define KRB5_ADDR_XEROX 0x06
135 #define KRB5_ADDR_ISO 0x07
136 #define KRB5_ADDR_DECNET 0x0c
137 #define KRB5_ADDR_APPLETALK 0x10
138 #define KRB5_ADDR_NETBIOS 0x14
139 #define KRB5_ADDR_IPv6 0x18
141 /* encryption type constants */
142 #define KRB5_ENCTYPE_NULL 0
143 #define KRB5_ENCTYPE_DES_CBC_CRC 1
144 #define KRB5_ENCTYPE_DES_CBC_MD4 2
145 #define KRB5_ENCTYPE_DES_CBC_MD5 3
146 #define KRB5_ENCTYPE_DES_CBC_RAW 4
147 #define KRB5_ENCTYPE_DES3_CBC_SHA 5
148 #define KRB5_ENCTYPE_DES3_CBC_RAW 6
149 #define KRB5_ENCTYPE_DES_HMAC_SHA1 8
150 #define KRB5_ENCTYPE_DES3_CBC_SHA1 16
151 #define KERB_ENCTYPE_RC4_HMAC 23
152 #define KERB_ENCTYPE_RC4_HMAC_EXP 24
153 #define KRB5_ENCTYPE_UNKNOWN 0x1ff
154 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
157 * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
159 * http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
161 * unless it's expired.
164 /* pre-authentication type constants */
165 #define KRB5_PA_TGS_REQ 1
166 #define KRB5_PA_ENC_TIMESTAMP 2
167 #define KRB5_PA_PW_SALT 3
168 #define KRB5_PA_ENC_ENCKEY 4
169 #define KRB5_PA_ENC_UNIX_TIME 5
170 #define KRB5_PA_ENC_SANDIA_SECURID 6
171 #define KRB5_PA_SESAME 7
172 #define KRB5_PA_OSF_DCE 8
173 #define KRB5_PA_CYBERSAFE_SECUREID 9
174 #define KRB5_PA_AFS3_SALT 10
175 #define KRB5_PA_ENCTYPE_INFO 11
176 #define KRB5_PA_SAM_CHALLENGE 12
177 #define KRB5_PA_SAM_RESPONSE 13
178 #define KRB5_PA_DASS 16
179 #define KRB5_PA_USE_SPECIFIED_KVNO 20
180 #define KRB5_PA_SAM_REDIRECT 21
181 #define KRB5_PA_GET_FROM_TYPED_DATA 22
182 #define KRB5_PA_SAM_ETYPE_INFO 23
183 #define KRB5_PA_ALT_PRINC 24
184 #define KRB5_PA_SAM_CHALLENGE2 30
185 #define KRB5_PA_SAM_RESPONSE2 31
186 #define KRB5_PA_PAC_REQUEST 128
188 /* Type tags within Ticket */
189 #define KRB5_TKT_TKT_VNO 0
190 #define KRB5_TKT_REALM 1
191 #define KRB5_TKT_SNAME 2
192 #define KRB5_TKT_ENC_PART 3
194 /* Principal name-type */
195 #define KRB5_NT_UNKNOWN 0
196 #define KRB5_NT_PRINCIPAL 1
197 #define KRB5_NT_SRV_INST 2
198 #define KRB5_NT_SRV_HST 3
199 #define KRB5_NT_SRV_XHST 4
200 #define KRB5_NT_UID 5
202 /* error table constants */
203 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
204 #define KRB5_ET_KRB5KDC_ERR_NONE 0
205 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP 1
206 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP 2
207 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO 3
208 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO 4
209 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO 5
210 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 6
211 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN 7
212 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE 8
213 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY 9
214 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE 10
215 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID 11
216 #define KRB5_ET_KRB5KDC_ERR_POLICY 12
217 #define KRB5_ET_KRB5KDC_ERR_BADOPTION 13
218 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP 14
219 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP 15
220 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP 16
221 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP 17
222 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED 18
223 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED 19
224 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED 20
225 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET 21
226 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET 22
227 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP 23
228 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED 24
229 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED 25
230 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH 26
231 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY 31
232 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED 32
233 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV 33
234 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT 34
235 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US 35
236 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH 36
237 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW 37
238 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR 38
239 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION 39
240 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE 40
241 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED 41
242 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER 42
243 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT 43
244 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER 44
245 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY 45
246 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL 46
247 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION 47
248 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD 48
249 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ 49
250 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM 50
251 #define KRB5_ET_KRB5KRB_ERR_GENERIC 60
252 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG 61
254 static const value_string krb5_error_codes[] = {
255 { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
256 { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
257 { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
258 { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
259 { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
260 { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
261 { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
262 { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
263 { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
264 { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
265 { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
266 { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
267 { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
268 { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
269 { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
270 { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
271 { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
272 { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
273 { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
274 { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
275 { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
276 { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
277 { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
278 { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
279 { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
280 { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
281 { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
282 { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
283 { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
284 { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
285 { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
286 { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
287 { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
288 { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
289 { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
290 { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
291 { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
292 { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
293 { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
294 { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
295 { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
296 { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
297 { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
298 { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
299 { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
300 { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
301 { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
302 { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
303 { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
308 static const value_string krb5_princ_types[] = {
309 { KRB5_NT_UNKNOWN , "Unknown" },
310 { KRB5_NT_PRINCIPAL , "Principal" },
311 { KRB5_NT_SRV_INST , "Service and Instance" },
312 { KRB5_NT_SRV_HST , "Service and Host" },
313 { KRB5_NT_SRV_XHST , "Service and Host Components" },
314 { KRB5_NT_UID , "Unique ID" },
318 static const value_string krb5_preauthentication_types[] = {
319 { KRB5_PA_TGS_REQ , "PA-TGS-REQ" },
320 { KRB5_PA_ENC_TIMESTAMP , "PA-ENC-TIMESTAMP" },
321 { KRB5_PA_PW_SALT , "PA-PW-SALT" },
322 { KRB5_PA_ENC_ENCKEY , "PA-ENC-ENCKEY" },
323 { KRB5_PA_ENC_UNIX_TIME , "PA-ENC-UNIX-TIME" },
324 { KRB5_PA_ENC_SANDIA_SECURID , "PA-PW-SALT" },
325 { KRB5_PA_SESAME , "PA-SESAME" },
326 { KRB5_PA_OSF_DCE , "PA-OSF-DCE" },
327 { KRB5_PA_CYBERSAFE_SECUREID , "PA-CYBERSAFE-SECURID" },
328 { KRB5_PA_AFS3_SALT , "PA-AFS3-SALT" },
329 { KRB5_PA_ENCTYPE_INFO , "PA-ENCTYPE-INFO" },
330 { KRB5_PA_SAM_CHALLENGE , "PA-SAM-CHALLENGE" },
331 { KRB5_PA_SAM_RESPONSE , "PA-SAM-RESPONSE" },
332 { KRB5_PA_DASS , "PA-DASS" },
333 { KRB5_PA_USE_SPECIFIED_KVNO , "PA-USE-SPECIFIED-KVNO" },
334 { KRB5_PA_SAM_REDIRECT , "PA-SAM-REDIRECT" },
335 { KRB5_PA_GET_FROM_TYPED_DATA , "PA-GET-FROM-TYPED-DATA" },
336 { KRB5_PA_SAM_ETYPE_INFO , "PA-SAM-ETYPE-INFO" },
337 { KRB5_PA_ALT_PRINC , "PA-ALT-PRINC" },
338 { KRB5_PA_SAM_CHALLENGE2 , "PA-SAM-CHALLENGE2" },
339 { KRB5_PA_SAM_RESPONSE2 , "PA-SAM-RESPONSE2" },
340 { KRB5_PA_PAC_REQUEST , "PA-PAC-REQUEST" },
344 static const value_string krb5_encryption_types[] = {
345 { KRB5_ENCTYPE_NULL , "NULL" },
346 { KRB5_ENCTYPE_DES_CBC_CRC , "des-cbc-crc" },
347 { KRB5_ENCTYPE_DES_CBC_MD4 , "des-cbc-md4" },
348 { KRB5_ENCTYPE_DES_CBC_MD5 , "des-cbc-md5" },
349 { KRB5_ENCTYPE_DES_CBC_RAW , "des-cbc-raw" },
350 { KRB5_ENCTYPE_DES3_CBC_SHA , "des3-cbc-sha" },
351 { KRB5_ENCTYPE_DES3_CBC_RAW , "des3-cbc-raw" },
352 { KRB5_ENCTYPE_DES_HMAC_SHA1 , "des-hmac-sha1" },
353 { KRB5_ENCTYPE_DES3_CBC_SHA1 , "des3-cbc-sha1" },
354 { KERB_ENCTYPE_RC4_HMAC , "rc4-hmac" },
355 { KERB_ENCTYPE_RC4_HMAC_EXP , "rc4-hmac-exp" },
356 { KRB5_ENCTYPE_UNKNOWN , "unknown" },
357 { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1 , "local-des3-hmac-sha1" },
361 static const value_string krb5_address_types[] = {
362 { KRB5_ADDR_IPv4, "IPv4"},
363 { KRB5_ADDR_CHAOS, "CHAOS"},
364 { KRB5_ADDR_XEROX, "XEROX"},
365 { KRB5_ADDR_ISO, "ISO"},
366 { KRB5_ADDR_DECNET, "DECNET"},
367 { KRB5_ADDR_APPLETALK, "APPLETALK"},
368 { KRB5_ADDR_NETBIOS, "NETBIOS"},
369 { KRB5_ADDR_IPv6, "IPv6"},
373 static const value_string krb5_msg_types[] = {
374 { KRB5_MSG_TGS_REQ, "TGS-REQ" },
375 { KRB5_MSG_TGS_REP, "TGS-REP" },
376 { KRB5_MSG_AS_REQ, "AS-REQ" },
377 { KRB5_MSG_AS_REP, "AS-REP" },
378 { KRB5_MSG_AP_REQ, "AP-REQ" },
379 { KRB5_MSG_AP_REP, "AP-REP" },
380 { KRB5_MSG_SAFE, "KRB-SAFE" },
381 { KRB5_MSG_PRIV, "KRB-PRIV" },
382 { KRB5_MSG_CRED, "KRB-CRED" },
383 { KRB5_MSG_ERROR, "KRB-ERROR" },
387 static int dissect_PrincipalName(char *title, ASN1_SCK *asn1p,
388 packet_info *pinfo, proto_tree *tree,
390 static int dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
391 proto_tree *tree, int start_offset);
392 static int dissect_EncryptedData(char *title, ASN1_SCK *asn1p,
393 packet_info *pinfo, proto_tree *tree,
395 static int dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
396 proto_tree *tree, int start_offset);
399 to_error_str(int ret) {
402 case ASN1_ERR_EOC_MISMATCH:
403 return("EOC mismatch");
405 case ASN1_ERR_WRONG_TYPE:
406 return("Wrong type for that item");
408 case ASN1_ERR_LENGTH_NOT_DEFINITE:
409 return("Length was indefinite");
411 case ASN1_ERR_LENGTH_MISMATCH:
412 return("Length mismatch");
414 case ASN1_ERR_WRONG_LENGTH_FOR_TYPE:
415 return("Wrong length for that item's type");
418 return("Unknown error");
422 krb_proto_tree_add_time(proto_tree *tree, tvbuff_t *tvb, int offset,
423 int str_len, char *name, guchar *str)
426 proto_tree_add_text(tree, tvb, offset, str_len,
427 "%s: %.4s-%.2s-%.2s %.2s:%.2s:%.2s (%.1s)",
428 name, str, str+4, str+6,
429 str+8, str+10, str+12,
435 * You must be kidding. I'm going to actually use a macro to do something?
439 #define KRB_HEAD_DECODE_OR_DIE(token) \
440 start = asn1p->offset; \
441 ret = asn1_header_decode (asn1p, &cls, &con, &tag, &def, &item_len); \
442 if (ret != ASN1_ERR_NOERROR) {\
443 if (check_col(pinfo->cinfo, COL_INFO)) \
444 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s, offset: %d", \
445 token, to_error_str(ret), start); \
449 if (check_col(pinfo->cinfo, COL_INFO)) \
450 col_add_fstr(pinfo->cinfo, COL_INFO, "not definite: %s", token); \
451 fprintf(stderr,"not definite: %s\n", token); \
454 offset += (asn1p->offset - start);
456 #define CHECK_APPLICATION_TYPE(expected_tag) \
457 (cls == ASN1_APL && con == ASN1_CON && tag == expected_tag)
459 #define DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag) \
460 if (!CHECK_APPLICATION_TYPE(expected_tag)) \
461 DIE_WITH_BAD_TYPE(token, expected_tag);
463 #define CHECK_CONTEXT_TYPE(expected_tag) \
464 (cls == ASN1_CTX && con == ASN1_CON && tag == expected_tag)
466 #define DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag) \
467 if (!CHECK_CONTEXT_TYPE(expected_tag)) \
468 DIE_WITH_BAD_TYPE(token, expected_tag);
470 #define DIE_WITH_BAD_TYPE(token, expected_tag) \
472 if (check_col(pinfo->cinfo, COL_INFO)) \
473 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s (tag=%d exp=%d, con=%d, cls=%d, offset=%0x)", \
474 token, to_error_str(ASN1_ERR_WRONG_TYPE), tag, expected_tag, con, cls, start); \
478 #define KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE(token, expected_tag) \
479 KRB_HEAD_DECODE_OR_DIE(token); \
480 DIE_IF_NOT_APPLICATION_TYPE(token, expected_tag);
482 #define KRB_DECODE_CONTEXT_HEAD_OR_DIE(token, expected_tag) \
483 KRB_HEAD_DECODE_OR_DIE(token); \
484 DIE_IF_NOT_CONTEXT_TYPE(token, expected_tag);
486 #define KRB_SEQ_HEAD_DECODE_OR_DIE(token) \
487 ret = asn1_sequence_decode (asn1p, &item_len, &header_len); \
488 if (ret != ASN1_ERR_NOERROR) {\
489 if (check_col(pinfo->cinfo, COL_INFO)) \
490 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
491 token, to_error_str(ret)); \
494 offset += header_len;
496 #define KRB_DECODE_OR_DIE(token, fn, val) \
497 ret = fn (asn1p, &val, &length); \
498 if (ret != ASN1_ERR_NOERROR) { \
499 if (check_col(pinfo->cinfo, COL_INFO)) \
500 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
501 token, to_error_str(ret)); \
505 #define KRB_DECODE_UINT32_OR_DIE(token, val) \
506 KRB_DECODE_OR_DIE(token, asn1_uint32_decode, val);
508 #define KRB_DECODE_STRING_OR_DIE(token, expected_tag, val, val_len, item_len) \
509 ret = asn1_string_decode (asn1p, &val, &val_len, &item_len, expected_tag); \
510 if (ret != ASN1_ERR_NOERROR) { \
511 if (check_col(pinfo->cinfo, COL_INFO)) \
512 col_add_fstr(pinfo->cinfo, COL_INFO, "ERROR: Problem at %s: %s", \
513 token, to_error_str(ret)); \
517 #define KRB_DECODE_OCTET_STRING_OR_DIE(token, val, val_len, item_len) \
518 KRB_DECODE_STRING_OR_DIE(token, ASN1_OTS, val, val_len, item_len)
520 #define KRB_DECODE_GENERAL_STRING_OR_DIE(token, val, val_len, item_len) \
521 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENSTR, val, val_len, item_len)
523 #define KRB_DECODE_GENERAL_TIME_OR_DIE(token, val, val_len, item_len) \
524 KRB_DECODE_STRING_OR_DIE(token, ASN1_GENTIM, val, val_len, item_len)
526 /* dissect_type_value_pair decodes (roughly) this:
533 which is all over the place in krb5 */
536 dissect_type_value_pair(ASN1_SCK *asn1p, int *inoff,
537 guint32 *type, int *type_len, int *type_off,
538 guchar **val, int *val_len, int *val_off) {
547 start = asn1p->offset;
548 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
549 offset += (asn1p->offset - start);
553 start = asn1p->offset;
554 asn1_header_decode (asn1p, &cls, &con, &tag, &def, &tmp_len);
555 offset += (asn1p->offset - start);
561 ret = asn1_uint32_decode(asn1p, type, type_len);
562 if (ret != ASN1_ERR_NOERROR) {
563 fprintf(stderr,"die: type_value_pair: type, %s\n", to_error_str(ret));
568 /* OCTET STRING (or generic data) */
570 start = asn1p->offset;
571 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
572 asn1_header_decode (asn1p, &cls, &con, &tag, &def, val_len);
573 offset += asn1p->offset - start;
579 asn1_string_value_decode (asn1p, *val_len, val);
581 *inoff = offset + *val_len;
585 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info)
588 proto_tree *kerberos_tree = NULL;
589 proto_tree *etype_tree = NULL;
590 proto_tree *preauth_tree = NULL;
591 proto_tree *request_tree = NULL;
592 proto_tree *additional_tickets_tree = NULL;
593 ASN1_SCK asn1, *asn1p = &asn1;
594 proto_item *item = NULL;
601 int start, end, message_end, sequence_end;
605 guint protocol_message_type;
609 guint32 preauth_type;
615 int tmp_pos1, tmp_pos2;
617 asn1_open(&asn1, tvb, 0);
620 KRB_HEAD_DECODE_OR_DIE("top");
621 protocol_message_type = tag;
623 item = proto_tree_add_item(tree, proto_kerberos, tvb, offset,
625 kerberos_tree = proto_item_add_subtree(item, ett_kerberos);
627 message_end = asn1p->offset + item_len;
630 KRB_HEAD_DECODE_OR_DIE("top2");
633 KRB_HEAD_DECODE_OR_DIE("version-wrap");
634 KRB_DECODE_UINT32_OR_DIE("version", version);
637 proto_tree_add_text(kerberos_tree, tvb, offset, length,
644 KRB_HEAD_DECODE_OR_DIE("message-type-wrap");
645 KRB_DECODE_UINT32_OR_DIE("message-type", msg_type);
648 proto_tree_add_text(kerberos_tree, tvb, offset, length,
650 val_to_str(msg_type, krb5_msg_types,
651 "Unknown msg type %#x"));
655 if (do_col_info & check_col(pinfo->cinfo, COL_INFO))
656 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(msg_type, krb5_msg_types,
657 "Unknown msg type %#x"));
659 /* is preauthentication present? */
660 KRB_HEAD_DECODE_OR_DIE("padata-or-body");
661 if (((protocol_message_type == KRB5_MSG_AS_REQ ||
662 protocol_message_type == KRB5_MSG_TGS_REQ) &&
663 tag == KRB5_KDC_REQ_PADATA) ||
664 ((protocol_message_type == KRB5_MSG_AS_REP ||
665 protocol_message_type == KRB5_MSG_TGS_REP) &&
666 tag == KRB5_KDC_REP_PADATA)) {
667 /* pre-authentication supplied */
670 item = proto_tree_add_text(kerberos_tree, tvb, offset,
671 item_len, "Pre-Authentication");
672 preauth_tree = proto_item_add_subtree(item, ett_preauth);
675 KRB_HEAD_DECODE_OR_DIE("sequence of pa-data");
676 end = asn1p->offset + item_len;
678 while(asn1p->offset < end) {
679 dissect_type_value_pair(asn1p, &offset,
680 &preauth_type, &item_len, &tmp_pos1,
681 &str, &str_len, &tmp_pos2);
684 proto_tree_add_text(preauth_tree, tvb, tmp_pos1,
685 item_len, "Type: %s",
686 val_to_str(preauth_type,
687 krb5_preauthentication_types,
688 "Unknown preauth type %#x"));
689 proto_tree_add_text(preauth_tree, tvb, tmp_pos2,
690 str_len, "Value: %s",
691 bytes_to_str(str, str_len));
694 KRB_HEAD_DECODE_OR_DIE("message-body");
697 switch (protocol_message_type) {
699 case KRB5_MSG_AS_REQ:
700 case KRB5_MSG_TGS_REQ:
702 AS-REQ ::= [APPLICATION 10] KDC-REQ
703 TGS-REQ ::= [APPLICATION 12] KDC-REQ
705 KDC-REQ ::= SEQUENCE {
708 padata[3] SEQUENCE OF PA-DATA OPTIONAL,
709 req-body[4] KDC-REQ-BODY
712 KDC-REQ-BODY ::= SEQUENCE {
713 kdc-options[0] KDCOptions,
714 cname[1] PrincipalName OPTIONAL,
715 -- Used only in AS-REQ
716 realm[2] Realm, -- Server's realm
717 -- Also client's in AS-REQ
718 sname[3] PrincipalName OPTIONAL,
719 from[4] KerberosTime OPTIONAL,
720 till[5] KerberosTime,
721 rtime[6] KerberosTime OPTIONAL,
723 etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
724 -- in preference order
725 addresses[9] HostAddresses OPTIONAL,
726 enc-authorization-data[10] EncryptedData OPTIONAL,
727 -- Encrypted AuthorizationData encoding
728 additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
733 KRB_HEAD_DECODE_OR_DIE("body-sequence");
735 item = proto_tree_add_text(kerberos_tree, tvb, offset,
736 item_len, "Request");
737 request_tree = proto_item_add_subtree(item, ett_request);
739 sequence_end = asn1p->offset + item_len;
742 KRB_HEAD_DECODE_OR_DIE("kdc options");
744 KRB_HEAD_DECODE_OR_DIE("kdc options:bits");
747 proto_tree_add_text(request_tree, tvb, offset, item_len,
749 tvb_bytes_to_str(asn1p->tvb, asn1p->offset,
753 asn1p->offset += item_len;
755 KRB_HEAD_DECODE_OR_DIE("Client Name or Realm");
757 if (CHECK_CONTEXT_TYPE(KRB5_BODY_CNAME)) {
758 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
759 request_tree, offset);
763 KRB_HEAD_DECODE_OR_DIE("Realm");
766 DIE_IF_NOT_CONTEXT_TYPE("Realm", KRB5_BODY_REALM);
767 KRB_DECODE_GENERAL_STRING_OR_DIE("Realm", str, str_len, item_len);
769 proto_tree_add_text(request_tree, tvb, offset, item_len,
770 "Realm: %.*s", str_len, str);
774 KRB_HEAD_DECODE_OR_DIE("Server Name");
775 if (CHECK_CONTEXT_TYPE(KRB5_BODY_SNAME)) {
776 item_len = dissect_PrincipalName("Server Name", asn1p, pinfo,
777 request_tree, offset);
781 KRB_HEAD_DECODE_OR_DIE("From or Till");
784 if (CHECK_CONTEXT_TYPE(KRB5_BODY_FROM)) {
785 KRB_DECODE_GENERAL_TIME_OR_DIE("From", str, str_len, item_len);
786 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
789 KRB_HEAD_DECODE_OR_DIE("Till");
792 DIE_IF_NOT_CONTEXT_TYPE("Till", KRB5_BODY_TILL);
793 KRB_DECODE_GENERAL_TIME_OR_DIE("Till", str, str_len, item_len);
794 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
798 KRB_HEAD_DECODE_OR_DIE("Renewable Until or Nonce");
799 if (CHECK_CONTEXT_TYPE(KRB5_BODY_RTIME)) {
800 KRB_DECODE_GENERAL_TIME_OR_DIE("Renewable Until", str, str_len, item_len);
801 krb_proto_tree_add_time(request_tree, asn1p->tvb, offset, item_len,
802 "Renewable Until", str);
804 KRB_HEAD_DECODE_OR_DIE("Nonce");
807 DIE_IF_NOT_CONTEXT_TYPE("Nonce", KRB5_BODY_NONCE);
808 KRB_DECODE_UINT32_OR_DIE("Nonce", tmp_int);
810 proto_tree_add_text(request_tree, tvb, offset, length,
816 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type spot",
818 KRB_HEAD_DECODE_OR_DIE("encryption type list");
820 item = proto_tree_add_text(request_tree, tvb, offset,
821 item_len, "Encryption Types");
822 etype_tree = proto_item_add_subtree(item, ett_etype);
824 total_len = item_len;
825 while(total_len > 0) {
826 KRB_DECODE_UINT32_OR_DIE("encryption type", tmp_int);
828 proto_tree_add_text(etype_tree, tvb, offset, length,
831 krb5_encryption_types,
832 "Unknown encryption type %#x"));
838 if (asn1p->offset >= sequence_end)
840 KRB_HEAD_DECODE_OR_DIE("addresses or enc-authorization-data");
841 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ADDRESSES)) {
842 /* addresses supplied */
844 length = dissect_Addresses(asn1p, pinfo, kerberos_tree,
849 if (asn1p->offset >= sequence_end)
851 KRB_HEAD_DECODE_OR_DIE("enc-authorization-data or additional-tickets");
854 if (CHECK_CONTEXT_TYPE(KRB5_BODY_ENC_AUTHORIZATION_DATA)) {
855 /* enc-authorization-data supplied */
856 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
857 kerberos_tree, offset);
861 if (asn1p->offset >= sequence_end)
863 KRB_HEAD_DECODE_OR_DIE("additional-tickets");
866 /* additional-tickets supplied */
868 item = proto_tree_add_text(kerberos_tree, tvb, offset,
869 item_len, "Additional Tickets");
870 additional_tickets_tree = proto_item_add_subtree(item, ett_additional_tickets);
872 end = asn1p->offset + item_len;
873 while(asn1p->offset < end) {
874 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
875 length = dissect_Ticket(asn1p, pinfo, additional_tickets_tree,
884 case KRB5_MSG_AS_REP:
885 case KRB5_MSG_TGS_REP:
887 AS-REP ::= [APPLICATION 11] KDC-REP
888 TGS-REP ::= [APPLICATION 13] KDC-REP
890 KDC-REP ::= SEQUENCE {
893 padata[2] SEQUENCE OF PA-DATA OPTIONAL,
895 cname[4] PrincipalName,
897 enc-part[6] EncryptedData
901 DIE_IF_NOT_CONTEXT_TYPE("crealm", KRB5_KDC_REP_CREALM);
902 KRB_DECODE_GENERAL_STRING_OR_DIE("realm name", str, str_len, item_len);
904 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
905 "Realm: %.*s", str_len, str);
909 KRB_DECODE_CONTEXT_HEAD_OR_DIE("cname", KRB5_KDC_REP_CNAME);
910 item_len = dissect_PrincipalName("Client Name", asn1p, pinfo,
911 kerberos_tree, offset);
916 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_KDC_REP_TICKET);
917 length = dissect_Ticket(asn1p, pinfo, kerberos_tree, offset);
922 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-msg-part",
923 KRB5_KDC_REP_ENC_PART);
924 length = dissect_EncryptedData("Encrypted Payload", asn1p, pinfo,
925 kerberos_tree, offset);
931 case KRB5_MSG_AP_REQ:
934 /* We pulled the header above */
936 KRB_HEAD_DECODE_OR_DIE("ap options:bits");
939 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
941 tvb_bytes_to_str(asn1p->tvb, asn1p->offset,
945 asn1p->offset += item_len;
947 KRB_DECODE_CONTEXT_HEAD_OR_DIE("ticket", KRB5_AP_REQ_TICKET);
948 length = dissect_Ticket(asn1p, pinfo, kerberos_tree, offset);
953 KRB_DECODE_CONTEXT_HEAD_OR_DIE("authenticator",
954 KRB5_AP_REQ_ENC_DATA);
955 length = dissect_EncryptedData("Authenticator", asn1p, pinfo,
956 kerberos_tree, offset);
962 case KRB5_MSG_AP_REP:
963 length = dissect_EncryptedData("EncPart", asn1p, pinfo,
964 kerberos_tree, offset);
972 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
975 ctime[2] KerberosTime OPTIONAL,
976 cusec[3] INTEGER OPTIONAL,
977 stime[4] KerberosTime,
979 error-code[6] INTEGER,
980 crealm[7] Realm OPTIONAL,
981 cname[8] PrincipalName OPTIONAL,
982 realm[9] Realm, -- Correct realm
983 sname[10] PrincipalName, -- Correct name
984 e-text[11] GeneralString OPTIONAL,
985 e-data[12] OCTET STRING OPTIONAL
992 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CTIME)) {
993 KRB_DECODE_GENERAL_TIME_OR_DIE("ctime", str, str_len, item_len);
994 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
997 KRB_HEAD_DECODE_OR_DIE("cusec");
1001 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CUSEC)) {
1002 KRB_DECODE_UINT32_OR_DIE("cusec", tmp_int);
1003 if (kerberos_tree) {
1004 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1010 KRB_HEAD_DECODE_OR_DIE("sutime");
1013 DIE_IF_NOT_CONTEXT_TYPE("sutime", KRB5_ERROR_STIME);
1014 KRB_DECODE_GENERAL_TIME_OR_DIE("stime", str, str_len, item_len);
1015 krb_proto_tree_add_time(kerberos_tree, asn1p->tvb, offset, item_len,
1019 KRB_HEAD_DECODE_OR_DIE("susec");
1020 DIE_IF_NOT_CONTEXT_TYPE("susec", KRB5_ERROR_SUSEC);
1021 KRB_DECODE_UINT32_OR_DIE("susec", tmp_int);
1022 if (kerberos_tree) {
1023 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1029 KRB_HEAD_DECODE_OR_DIE("errcode");
1030 DIE_IF_NOT_CONTEXT_TYPE("errcode", KRB5_ERROR_ERROR_CODE);
1031 KRB_DECODE_UINT32_OR_DIE("errcode", tmp_int);
1032 if (kerberos_tree) {
1033 proto_tree_add_text(kerberos_tree, tvb, offset, length,
1035 val_to_str(tmp_int, krb5_error_codes,
1036 "Unknown error code %#x"));
1039 KRB_HEAD_DECODE_OR_DIE("crealm");
1041 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CREALM)) {
1042 KRB_DECODE_GENERAL_STRING_OR_DIE("crealm", str, str_len, item_len);
1043 if (kerberos_tree) {
1044 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1045 "crealm: %.*s", str_len, str);
1048 KRB_HEAD_DECODE_OR_DIE("cname");
1051 if (CHECK_CONTEXT_TYPE(KRB5_ERROR_CNAME)) {
1052 item_len = dissect_PrincipalName("cname", asn1p, pinfo,
1053 kerberos_tree, offset);
1057 KRB_HEAD_DECODE_OR_DIE("realm");
1060 DIE_IF_NOT_CONTEXT_TYPE("realm", KRB5_ERROR_REALM);
1061 KRB_DECODE_GENERAL_STRING_OR_DIE("realm", str, str_len, item_len);
1062 if (kerberos_tree) {
1063 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1064 "realm: %.*s", str_len, str);
1067 KRB_HEAD_DECODE_OR_DIE("sname");
1069 DIE_IF_NOT_CONTEXT_TYPE("sname", KRB5_ERROR_SNAME);
1070 item_len = dissect_PrincipalName("sname", asn1p, pinfo,
1071 kerberos_tree, offset);
1076 if (asn1p->offset >= message_end)
1078 KRB_HEAD_DECODE_OR_DIE("e-text");
1079 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_ETEXT) ) {
1080 KRB_DECODE_GENERAL_STRING_OR_DIE("etext", str, str_len, item_len);
1081 if (kerberos_tree) {
1082 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1083 "etext: %.*s", str_len, str);
1086 if (asn1p->offset >= message_end)
1088 KRB_HEAD_DECODE_OR_DIE("e-data");
1091 if ( CHECK_CONTEXT_TYPE(KRB5_ERROR_EDATA) ) {
1095 KRB_DECODE_OCTET_STRING_OR_DIE("e-data", data, data_len, item_len);
1097 if (kerberos_tree) {
1098 proto_tree_add_text(kerberos_tree, tvb, offset, item_len,
1099 "Error Data: %s", bytes_to_str(data, data_len));
1110 dissect_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1112 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1113 col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1115 dissect_kerberos_main(tvb, pinfo, tree, TRUE);
1119 dissect_PrincipalName(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1120 proto_tree *tree, int start_offset)
1123 PrincipalName ::= SEQUENCE {
1124 name-type[0] INTEGER,
1125 name-string[1] SEQUENCE OF GeneralString
1128 proto_tree *princ_tree = NULL;
1129 int offset = start_offset;
1134 guint cls, con, tag;
1135 guint header_len, item_len, total_len, type_len;
1138 proto_item *item = NULL;
1147 /* principal name */
1148 KRB_SEQ_HEAD_DECODE_OR_DIE("principal section");
1151 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1152 (offset - start_offset) + item_len, "%s",
1154 princ_tree = proto_item_add_subtree(item, ett_princ);
1160 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal type", 0);
1161 KRB_DECODE_UINT32_OR_DIE("princ-type", princ_type);
1162 type_offset = offset;
1163 type_len = item_len;
1167 proto_tree_add_text(princ_tree, asn1p->tvb, type_offset, type_len,
1169 val_to_str(princ_type, krb5_princ_types,
1170 "Unknown name type %#x"));
1173 KRB_DECODE_CONTEXT_HEAD_OR_DIE("principal name-string", 1);
1174 KRB_SEQ_HEAD_DECODE_OR_DIE("principal name-string sequence-of");
1175 total_len = item_len;
1176 if (total_len == 0) {
1177 /* There are no name strings in this PrincipalName, so we can't
1178 put any in the top-level item. */
1179 return offset - start_offset;
1182 /* Put the first name string in the top-level item. */
1183 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1185 proto_item_set_text(item, "%s: %.*s", title, (int) name_len, name);
1186 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1187 "Name: %.*s", (int) name_len, name);
1189 total_len -= item_len;
1192 /* Now process the rest of the strings.
1193 XXX - put them in the item as well? */
1194 while (total_len > 0) {
1195 KRB_DECODE_GENERAL_STRING_OR_DIE("principal name", name, name_len, item_len);
1197 proto_tree_add_text(princ_tree, asn1p->tvb, offset, item_len,
1198 "Name: %.*s", (int) name_len, name);
1200 total_len -= item_len;
1203 return offset - start_offset;
1207 dissect_Addresses(ASN1_SCK *asn1p, packet_info *pinfo,
1208 proto_tree *tree, int start_offset) {
1209 proto_tree *address_tree = NULL;
1210 int offset = start_offset;
1213 guint cls, con, tag;
1217 proto_item *item = NULL;
1220 int tmp_pos1, tmp_pos2;
1221 guint32 address_type;
1226 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
1227 int netbios_name_type;
1229 KRB_HEAD_DECODE_OR_DIE("sequence of addresses");
1231 item = proto_tree_add_text(tree, asn1p->tvb, offset,
1232 item_len, "Addresses");
1233 address_tree = proto_item_add_subtree(item, ett_addresses);
1237 end = asn1p->offset + item_len;
1239 while(asn1p->offset < end) {
1240 dissect_type_value_pair(asn1p, &offset,
1241 &address_type, &item_len, &tmp_pos1,
1242 &str, &str_len, &tmp_pos2);
1245 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos1,
1246 item_len, "Type: %s",
1247 val_to_str(address_type, krb5_address_types,
1248 "Unknown address type %#x"));
1249 switch(address_type) {
1250 case KRB5_ADDR_IPv4:
1251 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1252 str_len, "Value: %d.%d.%d.%d",
1253 str[0], str[1], str[2], str[3]);
1256 case KRB5_ADDR_NETBIOS:
1257 if (str_len == NETBIOS_NAME_LEN) {
1258 netbios_name_type = process_netbios_name(str,
1260 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1262 "Value: %s<%02x> (%s)",
1263 netbios_name, netbios_name_type,
1264 netbios_name_type_descr(netbios_name_type));
1266 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1268 "Value (Invalid length %d, should be 16): \"%s\"",
1269 str_len, format_text(str, str_len));
1273 /* XXX - do KRB5_ADDR_IPv6 */
1276 proto_tree_add_text(address_tree, asn1p->tvb, tmp_pos2,
1277 str_len, "Value: %s",
1278 bytes_to_str(str, str_len));
1283 return offset - start_offset;
1287 dissect_EncryptedData(char *title, ASN1_SCK *asn1p, packet_info *pinfo,
1288 proto_tree *tree, int start_offset)
1291 EncryptedData ::= SEQUENCE {
1292 etype[0] INTEGER, -- EncryptionType
1293 kvno[1] INTEGER OPTIONAL,
1294 cipher[2] OCTET STRING -- ciphertext
1297 proto_tree *encr_tree = NULL;
1298 int offset = start_offset;
1301 guint cls, con, tag;
1302 guint header_len, item_len, data_len;
1305 proto_item *item = NULL;
1312 KRB_SEQ_HEAD_DECODE_OR_DIE("encrypted data section");
1315 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1316 (offset - start_offset) + item_len,
1317 "Encrypted Data: %s", title);
1318 encr_tree = proto_item_add_subtree(item, ett_princ);
1322 KRB_DECODE_CONTEXT_HEAD_OR_DIE("encryption type", 0);
1323 KRB_DECODE_UINT32_OR_DIE("encr-type", val);
1325 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1327 val_to_str(val, krb5_encryption_types,
1328 "Unknown encryption type %#x"));
1333 KRB_HEAD_DECODE_OR_DIE("kvno-wrap or cipher-wrap");
1334 if (CHECK_CONTEXT_TYPE(1)) {
1335 KRB_DECODE_UINT32_OR_DIE("kvno", val);
1337 proto_tree_add_text(encr_tree, asn1p->tvb, offset, length,
1341 KRB_HEAD_DECODE_OR_DIE("cipher-wrap");
1344 DIE_IF_NOT_CONTEXT_TYPE("cipher-wrap", 2);
1345 KRB_DECODE_OCTET_STRING_OR_DIE("cipher", data, data_len, item_len);
1348 proto_tree_add_text(encr_tree, asn1p->tvb, offset, item_len,
1349 "CipherText: %s", bytes_to_str(data, data_len));
1353 return offset - start_offset;
1357 dissect_Ticket(ASN1_SCK *asn1p, packet_info *pinfo,
1358 proto_tree *tree, int start_offset)
1361 Ticket ::= [APPLICATION 1] SEQUENCE {
1364 sname[2] PrincipalName,
1365 enc-part[3] EncryptedData
1368 proto_tree *ticket_tree = NULL;
1369 int offset = start_offset;
1372 guint cls, con, tag;
1373 guint header_len, total_len;
1377 proto_item *item = NULL;
1385 KRB_DECODE_APPLICATION_TAGGED_HEAD_OR_DIE("Ticket section", 1);
1386 KRB_SEQ_HEAD_DECODE_OR_DIE("Ticket sequence");
1387 total_len = item_len;
1390 item = proto_tree_add_text(tree, asn1p->tvb, start_offset,
1391 (offset - start_offset) + item_len,
1393 ticket_tree = proto_item_add_subtree(item, ett_ticket);
1397 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket tkt-vno", KRB5_TKT_TKT_VNO);
1398 KRB_DECODE_UINT32_OR_DIE("Ticket tkt-vno", val);
1400 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, length,
1401 "Version: %u", val);
1404 total_len -= length;
1407 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket realm", KRB5_TKT_REALM);
1408 KRB_DECODE_GENERAL_STRING_OR_DIE("Ticket realm string", str, str_len, item_len);
1410 proto_tree_add_text(ticket_tree, asn1p->tvb, offset, item_len,
1411 "Realm: %.*s", str_len, str);
1414 total_len -= item_len;
1416 /* server name (sname) */
1417 KRB_DECODE_CONTEXT_HEAD_OR_DIE("Ticket sname", KRB5_TKT_SNAME);
1418 item_len = dissect_PrincipalName("Service Name", asn1p, pinfo, ticket_tree,
1424 /* encrypted part */
1425 KRB_DECODE_CONTEXT_HEAD_OR_DIE("enc-part", KRB5_TKT_ENC_PART);
1426 length = dissect_EncryptedData("Ticket data", asn1p, pinfo, ticket_tree,
1432 return offset - start_offset;
1437 proto_register_kerberos(void) {
1439 static hf_register_info hf[] = {
1442 static gint *ett[] = {
1451 &ett_additional_tickets,
1453 proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
1455 proto_register_field_array(proto_kerberos, hf, array_length(hf));
1457 proto_register_subtree_array(ett, array_length(ett));
1461 proto_reg_handoff_kerberos(void)
1463 dissector_handle_t kerberos_handle;
1465 kerberos_handle = create_dissector_handle(dissect_kerberos, proto_kerberos);
1466 dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle);
1467 dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle);
1473 MISC definitions from RFC1510:
1475 Realm ::= GeneralString
1477 KerberosTime ::= GeneralizedTime
1479 HostAddress ::= SEQUENCE {
1480 addr-type[0] INTEGER,
1481 address[1] OCTET STRING
1484 HostAddresses ::= SEQUENCE OF SEQUENCE {
1485 addr-type[0] INTEGER,
1486 address[1] OCTET STRING
1489 AuthorizationData ::= SEQUENCE OF SEQUENCE {
1491 ad-data[1] OCTET STRING
1493 APOptions ::= BIT STRING {
1500 TicketFlags ::= BIT STRING {
1515 KDCOptions ::= BIT STRING {
1529 enc-tkt-in-skey(28),
1535 LastReq ::= SEQUENCE OF SEQUENCE {
1537 lr-value[1] KerberosTime
1540 Ticket ::= [APPLICATION 1] SEQUENCE {
1543 sname[2] PrincipalName,
1544 enc-part[3] EncryptedData
1547 -- Encrypted part of ticket
1548 EncTicketPart ::= [APPLICATION 3] SEQUENCE {
1549 flags[0] TicketFlags,
1550 key[1] EncryptionKey,
1552 cname[3] PrincipalName,
1553 transited[4] TransitedEncoding,
1554 authtime[5] KerberosTime,
1555 starttime[6] KerberosTime OPTIONAL,
1556 endtime[7] KerberosTime,
1557 renew-till[8] KerberosTime OPTIONAL,
1558 caddr[9] HostAddresses OPTIONAL,
1559 authorization-data[10] AuthorizationData OPTIONAL
1562 -- encoded Transited field
1563 TransitedEncoding ::= SEQUENCE {
1564 tr-type[0] INTEGER, -- must be registered
1565 contents[1] OCTET STRING
1568 -- Unencrypted authenticator
1569 Authenticator ::= [APPLICATION 2] SEQUENCE {
1570 authenticator-vno[0] INTEGER,
1572 cname[2] PrincipalName,
1573 cksum[3] Checksum OPTIONAL,
1575 ctime[5] KerberosTime,
1576 subkey[6] EncryptionKey OPTIONAL,
1577 seq-number[7] INTEGER OPTIONAL,
1578 authorization-data[8] AuthorizationData OPTIONAL
1581 PA-DATA ::= SEQUENCE {
1582 padata-type[1] INTEGER,
1583 padata-value[2] OCTET STRING,
1584 -- might be encoded AP-REQ
1587 padata-type ::= PA-ENC-TIMESTAMP
1588 padata-value ::= EncryptedData -- PA-ENC-TS-ENC
1590 PA-ENC-TS-ENC ::= SEQUENCE {
1591 patimestamp[0] KerberosTime, -- client's time
1592 pausec[1] INTEGER OPTIONAL
1595 EncASRepPart ::= [APPLICATION 25[25]] EncKDCRepPart
1596 EncTGSRepPart ::= [APPLICATION 26] EncKDCRepPart
1598 EncKDCRepPart ::= SEQUENCE {
1599 key[0] EncryptionKey,
1600 last-req[1] LastReq,
1602 key-expiration[3] KerberosTime OPTIONAL,
1603 flags[4] TicketFlags,
1604 authtime[5] KerberosTime,
1605 starttime[6] KerberosTime OPTIONAL,
1606 endtime[7] KerberosTime,
1607 renew-till[8] KerberosTime OPTIONAL,
1609 sname[10] PrincipalName,
1610 caddr[11] HostAddresses OPTIONAL
1613 AP-REQ ::= [APPLICATION 14] SEQUENCE {
1615 msg-type[1] INTEGER,
1616 ap-options[2] APOptions,
1618 authenticator[4] EncryptedData
1621 APOptions ::= BIT STRING {
1627 AP-REP ::= [APPLICATION 15] SEQUENCE {
1629 msg-type[1] INTEGER,
1630 enc-part[2] EncryptedData
1633 EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
1634 ctime[0] KerberosTime,
1636 subkey[2] EncryptionKey OPTIONAL,
1637 seq-number[3] INTEGER OPTIONAL
1640 KRB-SAFE ::= [APPLICATION 20] SEQUENCE {
1642 msg-type[1] INTEGER,
1643 safe-body[2] KRB-SAFE-BODY,
1647 KRB-SAFE-BODY ::= SEQUENCE {
1648 user-data[0] OCTET STRING,
1649 timestamp[1] KerberosTime OPTIONAL,
1650 usec[2] INTEGER OPTIONAL,
1651 seq-number[3] INTEGER OPTIONAL,
1652 s-address[4] HostAddress,
1653 r-address[5] HostAddress OPTIONAL
1656 KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
1658 msg-type[1] INTEGER,
1659 enc-part[3] EncryptedData
1662 EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE {
1663 user-data[0] OCTET STRING,
1664 timestamp[1] KerberosTime OPTIONAL,
1665 usec[2] INTEGER OPTIONAL,
1666 seq-number[3] INTEGER OPTIONAL,
1667 s-address[4] HostAddress, -- sender's addr
1668 r-address[5] HostAddress OPTIONAL
1672 KRB-CRED ::= [APPLICATION 22] SEQUENCE {
1674 msg-type[1] INTEGER, -- KRB_CRED
1675 tickets[2] SEQUENCE OF Ticket,
1676 enc-part[3] EncryptedData
1679 EncKrbCredPart ::= [APPLICATION 29] SEQUENCE {
1680 ticket-info[0] SEQUENCE OF KrbCredInfo,
1681 nonce[1] INTEGER OPTIONAL,
1682 timestamp[2] KerberosTime OPTIONAL,
1683 usec[3] INTEGER OPTIONAL,
1684 s-address[4] HostAddress OPTIONAL,
1685 r-address[5] HostAddress OPTIONAL
1688 KrbCredInfo ::= SEQUENCE {
1689 key[0] EncryptionKey,
1690 prealm[1] Realm OPTIONAL,
1691 pname[2] PrincipalName OPTIONAL,
1692 flags[3] TicketFlags OPTIONAL,
1693 authtime[4] KerberosTime OPTIONAL,
1694 starttime[5] KerberosTime OPTIONAL,
1695 endtime[6] KerberosTime OPTIONAL
1696 renew-till[7] KerberosTime OPTIONAL,
1697 srealm[8] Realm OPTIONAL,
1698 sname[9] PrincipalName OPTIONAL,
1699 caddr[10] HostAddresses OPTIONAL
1702 KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
1704 msg-type[1] INTEGER,
1705 ctime[2] KerberosTime OPTIONAL,
1706 cusec[3] INTEGER OPTIONAL,
1707 stime[4] KerberosTime,
1709 error-code[6] INTEGER,
1710 crealm[7] Realm OPTIONAL,
1711 cname[8] PrincipalName OPTIONAL,
1712 realm[9] Realm, -- Correct realm
1713 sname[10] PrincipalName, -- Correct name
1714 e-text[11] GeneralString OPTIONAL,
1715 e-data[12] OCTET STRING OPTIONAL
1718 e-data This field contains additional data about the error for use
1719 by the application to help it recover from or handle the
1720 error. If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
1721 the e-data field will contain an encoding of a sequence of
1722 padata fields, each corresponding to an acceptable pre-
1723 authentication method and optionally containing data for
1726 METHOD-DATA ::= SEQUENCE of PA-DATA
1728 If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
1729 contain an encoding of the following sequence:
1731 METHOD-DATA ::= SEQUENCE {
1732 method-type[0] INTEGER,
1733 method-data[1] OCTET STRING OPTIONAL
1736 EncryptionKey ::= SEQUENCE {
1738 keyvalue[1] OCTET STRING
1741 Checksum ::= SEQUENCE {
1742 cksumtype[0] INTEGER,
1743 checksum[1] OCTET STRING