From Yuriy Sidelnikov: handle the case where a presentation selector
[obnox/wireshark/wip.git] / packet-kerberos.c
1 /* packet-kerberos.c
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
7  *
8  * Ronnie Sahlberg (C) 2004, major rewrite for new ASN.1/BER API.
9  *
10  * See RFC 1510, and various I-Ds and other documents showing additions,
11  * e.g. ones listed under
12  *
13  *      http://www.isi.edu/people/bcn/krb-revisions/
14  *
15  * and
16  *
17  *      http://www.ietf.org/internet-drafts/draft-ietf-krb-wg-kerberos-clarifications-03.txt
18  *
19  * $Id: packet-kerberos.c,v 1.49 2004/02/25 07:52:37 sahlberg Exp $
20  *
21  * Ethereal - Network traffic analyzer
22  * By Gerald Combs <gerald@ethereal.com>
23  * Copyright 1998 Gerald Combs
24  *
25  * This program is free software; you can redistribute it and/or
26  * modify it under the terms of the GNU General Public License
27  * as published by the Free Software Foundation; either version 2
28  * of the License, or (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
38  */
39
40 #ifdef HAVE_CONFIG_H
41 # include "config.h"
42 #endif
43
44 #include <stdio.h>
45 #include <string.h>
46 #include <ctype.h>
47
48 #include <glib.h>
49
50 #include <epan/packet.h>
51
52 #include <epan/strutil.h>
53
54 #include "packet-netbios.h"
55 #include "packet-tcp.h"
56 #include "prefs.h"
57 #include "packet-ber.h"
58
59 #define UDP_PORT_KERBEROS               88
60 #define TCP_PORT_KERBEROS               88
61
62 /* Desegment Kerberos over TCP messages */
63 static gboolean krb_desegment = TRUE;
64
65 static gint proto_kerberos = -1;
66 static gint hf_krb_rm_reserved = -1;
67 static gint hf_krb_rm_reclen = -1;
68
69 static gint hf_krb_padata = -1;
70 static gint hf_krb_error_code = -1;
71 static gint hf_krb_ticket = -1;
72 static gint hf_krb_AP_REP_enc = -1;
73 static gint hf_krb_KDC_REP_enc = -1;
74 static gint hf_krb_tkt_vno = -1;
75 static gint hf_krb_e_data = -1;
76 static gint hf_krb_PA_PAC_REQUEST_flag = -1;
77 static gint hf_krb_encrypted_authenticator_data = -1;
78 static gint hf_krb_encrypted_PA_ENC_TIMESTAMP = -1;
79 static gint hf_krb_encrypted_PRIV = -1;
80 static gint hf_krb_encrypted_Ticket_data = -1;
81 static gint hf_krb_encrypted_AP_REP_data = -1;
82 static gint hf_krb_encrypted_KDC_REP_data = -1;
83 static gint hf_krb_PA_DATA_type = -1;
84 static gint hf_krb_PA_DATA_value = -1;
85 static gint hf_krb_realm = -1;
86 static gint hf_krb_crealm = -1;
87 static gint hf_krb_sname = -1;
88 static gint hf_krb_cname = -1;
89 static gint hf_krb_name_string = -1;
90 static gint hf_krb_e_text = -1;
91 static gint hf_krb_name_type = -1;
92 static gint hf_krb_from = -1;
93 static gint hf_krb_till = -1;
94 static gint hf_krb_rtime = -1;
95 static gint hf_krb_ctime = -1;
96 static gint hf_krb_cusec = -1;
97 static gint hf_krb_stime = -1;
98 static gint hf_krb_susec = -1;
99 static gint hf_krb_nonce = -1;
100 static gint hf_krb_etype = -1;
101 static gint hf_krb_etypes = -1;
102 static gint hf_krb_addr_type = -1;
103 static gint hf_krb_address_ip = -1;
104 static gint hf_krb_address_netbios = -1;
105 static gint hf_krb_msg_type = -1;
106 static gint hf_krb_pvno = -1;
107 static gint hf_krb_kvno = -1;
108 static gint hf_krb_HostAddress = -1;
109 static gint hf_krb_HostAddresses = -1;
110 static gint hf_krb_APOptions = -1;
111 static gint hf_krb_APOptions_use_session_key = -1;
112 static gint hf_krb_APOptions_mutual_required = -1;
113 static gint hf_krb_KDCOptions = -1;
114 static gint hf_krb_KDCOptions_forwardable = -1;
115 static gint hf_krb_KDCOptions_forwarded = -1;
116 static gint hf_krb_KDCOptions_proxyable = -1;
117 static gint hf_krb_KDCOptions_proxy = -1;
118 static gint hf_krb_KDCOptions_allow_postdate = -1;
119 static gint hf_krb_KDCOptions_postdated = -1;
120 static gint hf_krb_KDCOptions_renewable = -1;
121 static gint hf_krb_KDCOptions_renewable_ok = -1;
122 static gint hf_krb_KDCOptions_enc_tkt_in_skey = -1;
123 static gint hf_krb_KDCOptions_renew = -1;
124 static gint hf_krb_KDCOptions_validate = -1;
125 static gint hf_krb_KDC_REQ_BODY = -1;
126 static gint hf_krb_PRIV_BODY = -1;
127 static gint hf_krb_ENC_PRIV = -1;
128 static gint hf_krb_authenticator_enc = -1;
129 static gint hf_krb_ticket_enc = -1;
130
131 static gint ett_krb_kerberos = -1;
132 static gint ett_krb_KDC_REP_enc = -1;
133 static gint ett_krb_sname = -1;
134 static gint ett_krb_cname = -1;
135 static gint ett_krb_AP_REP_enc = -1;
136 static gint ett_krb_padata = -1;
137 static gint ett_krb_etypes = -1;
138 static gint ett_krb_PA_DATA_tree = -1;
139 static gint ett_krb_HostAddress = -1;
140 static gint ett_krb_HostAddresses = -1;
141 static gint ett_krb_authenticator_enc = -1;
142 static gint ett_krb_AP_Options = -1;
143 static gint ett_krb_KDC_Options = -1;
144 static gint ett_krb_request = -1;
145 static gint ett_krb_recordmark = -1;
146 static gint ett_krb_ticket = -1;
147 static gint ett_krb_ticket_enc = -1;
148 static gint ett_krb_PRIV = -1;
149 static gint ett_krb_PRIV_enc = -1;
150
151
152 guint32 krb5_error_code;
153
154
155 static int do_col_info;
156
157 /* TCP Record Mark */
158 #define KRB_RM_RESERVED 0x80000000L
159 #define KRB_RM_RECLEN   0x7fffffffL
160
161 #define KRB5_MSG_AS_REQ   10    /* AS-REQ type */
162 #define KRB5_MSG_AS_REP   11    /* AS-REP type */
163 #define KRB5_MSG_TGS_REQ  12    /* TGS-REQ type */
164 #define KRB5_MSG_TGS_REP  13    /* TGS-REP type */
165 #define KRB5_MSG_AP_REQ   14    /* AP-REQ type */
166 #define KRB5_MSG_AP_REP   15    /* AP-REP type */
167
168 #define KRB5_MSG_SAFE     20    /* KRB-SAFE type */
169 #define KRB5_MSG_PRIV     21    /* KRB-PRIV type */
170 #define KRB5_MSG_CRED     22    /* KRB-CRED type */
171 #define KRB5_MSG_ERROR    30    /* KRB-ERROR type */
172
173 /* address type constants */
174 #define KRB5_ADDR_IPv4       0x02
175 #define KRB5_ADDR_CHAOS      0x05
176 #define KRB5_ADDR_XEROX      0x06
177 #define KRB5_ADDR_ISO        0x07
178 #define KRB5_ADDR_DECNET     0x0c
179 #define KRB5_ADDR_APPLETALK  0x10
180 #define KRB5_ADDR_NETBIOS    0x14
181 #define KRB5_ADDR_IPv6       0x18
182
183 /* encryption type constants */
184 #define KRB5_ENCTYPE_NULL                0
185 #define KRB5_ENCTYPE_DES_CBC_CRC         1
186 #define KRB5_ENCTYPE_DES_CBC_MD4         2
187 #define KRB5_ENCTYPE_DES_CBC_MD5         3
188 #define KRB5_ENCTYPE_DES_CBC_RAW         4
189 #define KRB5_ENCTYPE_DES3_CBC_SHA        5
190 #define KRB5_ENCTYPE_DES3_CBC_RAW        6
191 #define KRB5_ENCTYPE_DES_HMAC_SHA1       8
192 #define KRB5_ENCTYPE_DES3_CBC_SHA1       16
193 #define KERB_ENCTYPE_RC4_HMAC            23 
194 #define KERB_ENCTYPE_RC4_HMAC_EXP        24
195 #define KRB5_ENCTYPE_UNKNOWN                0x1ff
196 #define KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1   0x7007
197
198 /*
199  * For KERB_ENCTYPE_RC4_HMAC and KERB_ENCTYPE_RC4_HMAC_EXP, see
200  *
201  *      http://www.ietf.org/internet-drafts/draft-brezak-win2k-krb-rc4-hmac-04.txt
202  *
203  * unless it's expired.
204  */
205
206 /* pre-authentication type constants */
207 #define KRB5_PA_TGS_REQ                1
208 #define KRB5_PA_ENC_TIMESTAMP          2
209 #define KRB5_PA_PW_SALT                3
210 #define KRB5_PA_ENC_ENCKEY             4
211 #define KRB5_PA_ENC_UNIX_TIME          5
212 #define KRB5_PA_ENC_SANDIA_SECURID     6
213 #define KRB5_PA_SESAME                 7
214 #define KRB5_PA_OSF_DCE                8
215 #define KRB5_PA_CYBERSAFE_SECUREID     9
216 #define KRB5_PA_AFS3_SALT              10
217 #define KRB5_PA_ENCTYPE_INFO           11
218 #define KRB5_PA_SAM_CHALLENGE          12
219 #define KRB5_PA_SAM_RESPONSE           13
220 #define KRB5_PA_DASS                   16
221 #define KRB5_PA_USE_SPECIFIED_KVNO     20
222 #define KRB5_PA_SAM_REDIRECT           21
223 #define KRB5_PA_GET_FROM_TYPED_DATA    22
224 #define KRB5_PA_SAM_ETYPE_INFO         23
225 #define KRB5_PA_ALT_PRINC              24
226 #define KRB5_PA_SAM_CHALLENGE2         30
227 #define KRB5_PA_SAM_RESPONSE2          31
228 #define KRB5_PA_PAC_REQUEST            128
229
230 /* Principal name-type */
231 #define KRB5_NT_UNKNOWN     0
232 #define KRB5_NT_PRINCIPAL   1
233 #define KRB5_NT_SRV_INST    2   
234 #define KRB5_NT_SRV_HST     3
235 #define KRB5_NT_SRV_XHST    4
236 #define KRB5_NT_UID     5
237
238 /* error table constants */
239 /* I prefixed the krb5_err.et constant names with KRB5_ET_ for these */
240 #define KRB5_ET_KRB5KDC_ERR_NONE                         0
241 #define KRB5_ET_KRB5KDC_ERR_NAME_EXP                     1
242 #define KRB5_ET_KRB5KDC_ERR_SERVICE_EXP                  2
243 #define KRB5_ET_KRB5KDC_ERR_BAD_PVNO                     3
244 #define KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO              4
245 #define KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO              5
246 #define KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN          6
247 #define KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN          7
248 #define KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE         8
249 #define KRB5_ET_KRB5KDC_ERR_NULL_KEY                     9
250 #define KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE              10
251 #define KRB5_ET_KRB5KDC_ERR_NEVER_VALID                  11
252 #define KRB5_ET_KRB5KDC_ERR_POLICY                       12
253 #define KRB5_ET_KRB5KDC_ERR_BADOPTION                    13
254 #define KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP                 14
255 #define KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP               15
256 #define KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP           16
257 #define KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP                17
258 #define KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED               18
259 #define KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED              19
260 #define KRB5_ET_KRB5KDC_ERR_TGT_REVOKED                  20
261 #define KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET                21
262 #define KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET               22
263 #define KRB5_ET_KRB5KDC_ERR_KEY_EXP                      23
264 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED               24
265 #define KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED             25
266 #define KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH               26
267 #define KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY             31
268 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED               32
269 #define KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV                   33
270 #define KRB5_ET_KRB5KRB_AP_ERR_REPEAT                    34
271 #define KRB5_ET_KRB5KRB_AP_ERR_NOT_US                    35
272 #define KRB5_ET_KRB5KRB_AP_ERR_BADMATCH                  36
273 #define KRB5_ET_KRB5KRB_AP_ERR_SKEW                      37
274 #define KRB5_ET_KRB5KRB_AP_ERR_BADADDR                   38
275 #define KRB5_ET_KRB5KRB_AP_ERR_BADVERSION                39
276 #define KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE                  40
277 #define KRB5_ET_KRB5KRB_AP_ERR_MODIFIED                  41
278 #define KRB5_ET_KRB5KRB_AP_ERR_BADORDER                  42
279 #define KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT                43
280 #define KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER                 44
281 #define KRB5_ET_KRB5KRB_AP_ERR_NOKEY                     45
282 #define KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL                  46
283 #define KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION              47
284 #define KRB5_ET_KRB5KRB_AP_ERR_METHOD                    48
285 #define KRB5_ET_KRB5KRB_AP_ERR_BADSEQ                    49
286 #define KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM               50
287 #define KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG             52
288 #define KRB5_ET_KRB5KRB_ERR_GENERIC                      60
289 #define KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG                61
290
291 static const value_string krb5_error_codes[] = {
292         { KRB5_ET_KRB5KDC_ERR_NONE, "KRB5KDC_ERR_NONE" },
293         { KRB5_ET_KRB5KDC_ERR_NAME_EXP, "KRB5KDC_ERR_NAME_EXP" },
294         { KRB5_ET_KRB5KDC_ERR_SERVICE_EXP, "KRB5KDC_ERR_SERVICE_EXP" },
295         { KRB5_ET_KRB5KDC_ERR_BAD_PVNO, "KRB5KDC_ERR_BAD_PVNO" },
296         { KRB5_ET_KRB5KDC_ERR_C_OLD_MAST_KVNO, "KRB5KDC_ERR_C_OLD_MAST_KVNO" },
297         { KRB5_ET_KRB5KDC_ERR_S_OLD_MAST_KVNO, "KRB5KDC_ERR_S_OLD_MAST_KVNO" },
298         { KRB5_ET_KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN" },
299         { KRB5_ET_KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN" },
300         { KRB5_ET_KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE, "KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE" },
301         { KRB5_ET_KRB5KDC_ERR_NULL_KEY, "KRB5KDC_ERR_NULL_KEY" },
302         { KRB5_ET_KRB5KDC_ERR_CANNOT_POSTDATE, "KRB5KDC_ERR_CANNOT_POSTDATE" },
303         { KRB5_ET_KRB5KDC_ERR_NEVER_VALID, "KRB5KDC_ERR_NEVER_VALID" },
304         { KRB5_ET_KRB5KDC_ERR_POLICY, "KRB5KDC_ERR_POLICY" },
305         { KRB5_ET_KRB5KDC_ERR_BADOPTION, "KRB5KDC_ERR_BADOPTION" },
306         { KRB5_ET_KRB5KDC_ERR_ETYPE_NOSUPP, "KRB5KDC_ERR_ETYPE_NOSUPP" },
307         { KRB5_ET_KRB5KDC_ERR_SUMTYPE_NOSUPP, "KRB5KDC_ERR_SUMTYPE_NOSUPP" },
308         { KRB5_ET_KRB5KDC_ERR_PADATA_TYPE_NOSUPP, "KRB5KDC_ERR_PADATA_TYPE_NOSUPP" },
309         { KRB5_ET_KRB5KDC_ERR_TRTYPE_NOSUPP, "KRB5KDC_ERR_TRTYPE_NOSUPP" },
310         { KRB5_ET_KRB5KDC_ERR_CLIENT_REVOKED, "KRB5KDC_ERR_CLIENT_REVOKED" },
311         { KRB5_ET_KRB5KDC_ERR_SERVICE_REVOKED, "KRB5KDC_ERR_SERVICE_REVOKED" },
312         { KRB5_ET_KRB5KDC_ERR_TGT_REVOKED, "KRB5KDC_ERR_TGT_REVOKED" },
313         { KRB5_ET_KRB5KDC_ERR_CLIENT_NOTYET, "KRB5KDC_ERR_CLIENT_NOTYET" },
314         { KRB5_ET_KRB5KDC_ERR_SERVICE_NOTYET, "KRB5KDC_ERR_SERVICE_NOTYET" },
315         { KRB5_ET_KRB5KDC_ERR_KEY_EXP, "KRB5KDC_ERR_KEY_EXP" },
316         { KRB5_ET_KRB5KDC_ERR_PREAUTH_FAILED, "KRB5KDC_ERR_PREAUTH_FAILED" },
317         { KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED, "KRB5KDC_ERR_PREAUTH_REQUIRED" },
318         { KRB5_ET_KRB5KDC_ERR_SERVER_NOMATCH, "KRB5KDC_ERR_SERVER_NOMATCH" },
319         { KRB5_ET_KRB5KRB_AP_ERR_BAD_INTEGRITY, "KRB5KRB_AP_ERR_BAD_INTEGRITY" },
320         { KRB5_ET_KRB5KRB_AP_ERR_TKT_EXPIRED, "KRB5KRB_AP_ERR_TKT_EXPIRED" },
321         { KRB5_ET_KRB5KRB_AP_ERR_TKT_NYV, "KRB5KRB_AP_ERR_TKT_NYV" },
322         { KRB5_ET_KRB5KRB_AP_ERR_REPEAT, "KRB5KRB_AP_ERR_REPEAT" },
323         { KRB5_ET_KRB5KRB_AP_ERR_NOT_US, "KRB5KRB_AP_ERR_NOT_US" },
324         { KRB5_ET_KRB5KRB_AP_ERR_BADMATCH, "KRB5KRB_AP_ERR_BADMATCH" },
325         { KRB5_ET_KRB5KRB_AP_ERR_SKEW, "KRB5KRB_AP_ERR_SKEW" },
326         { KRB5_ET_KRB5KRB_AP_ERR_BADADDR, "KRB5KRB_AP_ERR_BADADDR" },
327         { KRB5_ET_KRB5KRB_AP_ERR_BADVERSION, "KRB5KRB_AP_ERR_BADVERSION" },
328         { KRB5_ET_KRB5KRB_AP_ERR_MSG_TYPE, "KRB5KRB_AP_ERR_MSG_TYPE" },
329         { KRB5_ET_KRB5KRB_AP_ERR_MODIFIED, "KRB5KRB_AP_ERR_MODIFIED" },
330         { KRB5_ET_KRB5KRB_AP_ERR_BADORDER, "KRB5KRB_AP_ERR_BADORDER" },
331         { KRB5_ET_KRB5KRB_AP_ERR_ILL_CR_TKT, "KRB5KRB_AP_ERR_ILL_CR_TKT" },
332         { KRB5_ET_KRB5KRB_AP_ERR_BADKEYVER, "KRB5KRB_AP_ERR_BADKEYVER" },
333         { KRB5_ET_KRB5KRB_AP_ERR_NOKEY, "KRB5KRB_AP_ERR_NOKEY" },
334         { KRB5_ET_KRB5KRB_AP_ERR_MUT_FAIL, "KRB5KRB_AP_ERR_MUT_FAIL" },
335         { KRB5_ET_KRB5KRB_AP_ERR_BADDIRECTION, "KRB5KRB_AP_ERR_BADDIRECTION" },
336         { KRB5_ET_KRB5KRB_AP_ERR_METHOD, "KRB5KRB_AP_ERR_METHOD" },
337         { KRB5_ET_KRB5KRB_AP_ERR_BADSEQ, "KRB5KRB_AP_ERR_BADSEQ" },
338         { KRB5_ET_KRB5KRB_AP_ERR_INAPP_CKSUM, "KRB5KRB_AP_ERR_INAPP_CKSUM" },
339         { KRB5_ET_KRB5KRB_ERR_RESPONSE_TOO_BIG, "KRB5KRB_ERR_RESPONSE_TOO_BIG"},
340         { KRB5_ET_KRB5KRB_ERR_GENERIC, "KRB5KRB_ERR_GENERIC" },
341         { KRB5_ET_KRB5KRB_ERR_FIELD_TOOLONG, "KRB5KRB_ERR_FIELD_TOOLONG" },
342         { 0, NULL }
343 };
344
345
346 static const value_string krb5_princ_types[] = {
347     { KRB5_NT_UNKNOWN              , "Unknown" },
348     { KRB5_NT_PRINCIPAL            , "Principal" },
349     { KRB5_NT_SRV_INST             , "Service and Instance" },
350     { KRB5_NT_SRV_HST              , "Service and Host" },
351     { KRB5_NT_SRV_XHST             , "Service and Host Components" },
352     { KRB5_NT_UID                  , "Unique ID" },
353     { 0                            , NULL },
354 };
355
356 static const value_string krb5_preauthentication_types[] = {
357     { KRB5_PA_TGS_REQ              , "PA-TGS-REQ" },
358     { KRB5_PA_ENC_TIMESTAMP        , "PA-ENC-TIMESTAMP" },
359     { KRB5_PA_PW_SALT              , "PA-PW-SALT" },
360     { KRB5_PA_ENC_ENCKEY           , "PA-ENC-ENCKEY" },
361     { KRB5_PA_ENC_UNIX_TIME        , "PA-ENC-UNIX-TIME" },
362     { KRB5_PA_ENC_SANDIA_SECURID   , "PA-PW-SALT" },
363     { KRB5_PA_SESAME               , "PA-SESAME" },
364     { KRB5_PA_OSF_DCE              , "PA-OSF-DCE" },
365     { KRB5_PA_CYBERSAFE_SECUREID   , "PA-CYBERSAFE-SECURID" },
366     { KRB5_PA_AFS3_SALT            , "PA-AFS3-SALT" },
367     { KRB5_PA_ENCTYPE_INFO         , "PA-ENCTYPE-INFO" },
368     { KRB5_PA_SAM_CHALLENGE        , "PA-SAM-CHALLENGE" },
369     { KRB5_PA_SAM_RESPONSE         , "PA-SAM-RESPONSE" },
370     { KRB5_PA_DASS                 , "PA-DASS" },
371     { KRB5_PA_USE_SPECIFIED_KVNO   , "PA-USE-SPECIFIED-KVNO" },
372     { KRB5_PA_SAM_REDIRECT         , "PA-SAM-REDIRECT" },
373     { KRB5_PA_GET_FROM_TYPED_DATA  , "PA-GET-FROM-TYPED-DATA" },
374     { KRB5_PA_SAM_ETYPE_INFO       , "PA-SAM-ETYPE-INFO" },
375     { KRB5_PA_ALT_PRINC            , "PA-ALT-PRINC" },
376     { KRB5_PA_SAM_CHALLENGE2       , "PA-SAM-CHALLENGE2" },
377     { KRB5_PA_SAM_RESPONSE2        , "PA-SAM-RESPONSE2" },
378     { KRB5_PA_PAC_REQUEST          , "PA-PAC-REQUEST" },
379     { 0                            , NULL },
380 };
381
382 static const value_string krb5_encryption_types[] = {
383     { KRB5_ENCTYPE_NULL           , "NULL" },
384     { KRB5_ENCTYPE_DES_CBC_CRC    , "des-cbc-crc" },
385     { KRB5_ENCTYPE_DES_CBC_MD4    , "des-cbc-md4" },
386     { KRB5_ENCTYPE_DES_CBC_MD5    , "des-cbc-md5" },
387     { KRB5_ENCTYPE_DES_CBC_RAW    , "des-cbc-raw" },
388     { KRB5_ENCTYPE_DES3_CBC_SHA   , "des3-cbc-sha" },
389     { KRB5_ENCTYPE_DES3_CBC_RAW   , "des3-cbc-raw" },
390     { KRB5_ENCTYPE_DES_HMAC_SHA1  , "des-hmac-sha1" },
391     { KRB5_ENCTYPE_DES3_CBC_SHA1  , "des3-cbc-sha1" },
392     { KERB_ENCTYPE_RC4_HMAC       , "rc4-hmac" },
393     { KERB_ENCTYPE_RC4_HMAC_EXP   , "rc4-hmac-exp" },
394     { KRB5_ENCTYPE_UNKNOWN        , "unknown" },
395     { KRB5_ENCTYPE_LOCAL_DES3_HMAC_SHA1    , "local-des3-hmac-sha1" },
396     { 0                            , NULL },
397 };
398
399 static const value_string krb5_address_types[] = {
400     { KRB5_ADDR_IPv4,           "IPv4"},
401     { KRB5_ADDR_CHAOS,          "CHAOS"},
402     { KRB5_ADDR_XEROX,          "XEROX"},
403     { KRB5_ADDR_ISO,            "ISO"},
404     { KRB5_ADDR_DECNET,         "DECNET"},
405     { KRB5_ADDR_APPLETALK,      "APPLETALK"},
406     { KRB5_ADDR_NETBIOS,        "NETBIOS"},
407     { KRB5_ADDR_IPv6,           "IPv6"},
408     { 0,                        NULL },
409 };
410
411 static const value_string krb5_msg_types[] = {
412         { KRB5_MSG_TGS_REQ,     "TGS-REQ" },
413         { KRB5_MSG_TGS_REP,     "TGS-REP" },
414         { KRB5_MSG_AS_REQ,      "AS-REQ" },
415         { KRB5_MSG_AS_REP,      "AS-REP" },
416         { KRB5_MSG_AP_REQ,      "AP-REQ" },
417         { KRB5_MSG_AP_REP,      "AP-REP" },
418         { KRB5_MSG_SAFE,        "KRB-SAFE" },
419         { KRB5_MSG_PRIV,        "KRB-PRIV" },
420         { KRB5_MSG_CRED,        "KRB-CRED" },
421         { KRB5_MSG_ERROR,       "KRB-ERROR" },
422         { 0,                    NULL },
423 };
424
425
426
427
428 static int dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
429 static int dissect_krb5_KDC_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
430 static int dissect_krb5_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
431 static int dissect_krb5_AP_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
432 static int dissect_krb5_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
433 static int dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
434 static int dissect_krb5_ERROR(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
435
436 static const ber_choice kerberos_applications_choice[] = {
437         { BER_CLASS_APP,        KRB5_MSG_AS_REQ,        dissect_krb5_KDC_REQ },
438         { BER_CLASS_APP,        KRB5_MSG_AS_REP,        dissect_krb5_KDC_REP },
439         { BER_CLASS_APP,        KRB5_MSG_TGS_REQ,       dissect_krb5_KDC_REQ },
440         { BER_CLASS_APP,        KRB5_MSG_TGS_REP,       dissect_krb5_KDC_REP },
441         { BER_CLASS_APP,        KRB5_MSG_AP_REQ,        dissect_krb5_AP_REQ },
442         { BER_CLASS_APP,        KRB5_MSG_AP_REP,        dissect_krb5_AP_REP },
443         { BER_CLASS_APP,        KRB5_MSG_PRIV,          dissect_krb5_PRIV },
444         { BER_CLASS_APP,        KRB5_MSG_ERROR,         dissect_krb5_ERROR },
445         { 0, 0, NULL }
446 };
447
448
449 static int 
450 dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
451 {
452         offset=dissect_ber_choice(pinfo, tree, tvb, offset, kerberos_applications_choice, -1, -1);
453         return offset;
454 }
455
456
457 static const true_false_string krb5_apoptions_use_session_key = {
458         "USE SESSION KEY to encrypt the ticket",
459         "Do NOT use the session key to encrypt the ticket"
460 };
461 static const true_false_string krb5_apoptions_mutual_required = {
462         "MUTUAL authentication is REQUIRED",
463         "Mutual authentication is NOT required"
464 };
465
466 static int
467 dissect_krb5_APOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
468 {
469         unsigned char options[4]={0,0,0,0};
470         proto_item *item;
471         proto_tree *flags_tree;
472
473         offset=dissect_ber_bitstring(pinfo, tree, tvb, offset, hf_krb_APOptions, ett_krb_AP_Options, options, 4, &item, &flags_tree);
474
475         /* use session key */
476         proto_tree_add_boolean(flags_tree, hf_krb_APOptions_use_session_key , tvb, 0, 0, (options[0]&0x40)?0x40000000:0);
477         if(options[0]&0x40){
478                 if(item){
479                         proto_item_append_text(item, " Use-Session-Key");
480                 }
481         }
482         /* mutual required */
483         proto_tree_add_boolean(flags_tree, hf_krb_APOptions_mutual_required , tvb, 0, 0, (options[0]&0x20)?0x20000000:0);
484         if(options[0]&0x20){
485                 if(item){
486                         proto_item_append_text(item, " Mutual-Required");
487                 }
488         }
489
490         return offset;
491 }
492
493
494
495
496
497
498
499 static const true_false_string krb5_kdcoptions_forwardable = {
500         "FORWARDABLE tickets are allowed/requested",
501         "Do NOT use forwardable tickets"
502 };
503 static const true_false_string krb5_kdcoptions_forwarded = {
504         "This ticket has been FORWARDED",
505         "This is NOT a forwarded ticket"
506 };
507 static const true_false_string krb5_kdcoptions_proxyable = {
508         "PROXIABLE tickets are allowed/requested",
509         "Do NOT use proxiable tickets"
510 };
511 static const true_false_string krb5_kdcoptions_proxy = {
512         "This is a PROXY ticket",
513         "This ticket has NOT been proxied"
514 };
515 static const true_false_string krb5_kdcoptions_allow_postdate = {
516         "We allow the ticket to be POSTDATED",
517         "We do NOT allow the ticket to be postdated"
518 };
519 static const true_false_string krb5_kdcoptions_postdated = {
520         "This ticket is POSTDATED",
521         "This ticket is NOT postdated"
522 };
523 static const true_false_string krb5_kdcoptions_renewable = {
524         "This ticket is RENEWABLE",
525         "This ticket is NOT renewable"
526 };
527 static const true_false_string krb5_kdcoptions_renewable_ok = {
528         "We accept RENEWED tickets",
529         "We do NOT accept renewed tickets"
530 };
531 static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
532         "ENCrypt TKT in SKEY",
533         "Do NOT encrypt the tkt inside the skey"
534 };
535 static const true_false_string krb5_kdcoptions_renew = {
536         "This is a request to RENEW a ticket",
537         "This is NOT a request to renew a ticket"
538 };
539 static const true_false_string krb5_kdcoptions_validate = {
540         "This is a request to VALIDATE a postdated ticket",
541         "This is NOT a request to validate a postdated ticket"
542 };
543
544 static int
545 dissect_krb5_KDCOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
546 {
547         unsigned char options[4]={0,0,0,0};
548         proto_item *item;
549         proto_tree *flags_tree;
550
551         offset=dissect_ber_bitstring(pinfo, tree, tvb, offset, hf_krb_KDCOptions, ett_krb_KDC_Options, options, 4, &item, &flags_tree);
552
553         /* forwardable */
554         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_forwardable , tvb, 0, 0, (options[0]&0x40)?0x40000000:0);
555         if(options[0]&0x40){
556                 if(item){
557                         proto_item_append_text(item, " Forwardable");
558                 }
559         }
560         /* forwarded */
561         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_forwarded , tvb, 0, 0, (options[0]&0x20)?0x20000000:0);
562         if(options[0]&0x20){
563                 if(item){
564                         proto_item_append_text(item, " Forwarded");
565                 }
566         }
567         /* proxyable */
568         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_proxyable , tvb, 0, 0, (options[0]&0x10)?0x10000000:0);
569         if(options[0]&0x10){
570                 if(item){
571                         proto_item_append_text(item, " Proxyable");
572                 }
573         }
574         /* proxy */
575         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_proxy , tvb, 0, 0, (options[0]&0x08)?0x08000000:0);
576         if(options[0]&0x08){
577                 if(item){
578                         proto_item_append_text(item, " Proxy");
579                 }
580         }
581         /* allow-postdate */
582         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_allow_postdate , tvb, 0, 0, (options[0]&0x04)?0x04000000:0);
583         if(options[0]&0x04){
584                 if(item){
585                         proto_item_append_text(item, " Allow-Postdate");
586                 }
587         }
588         /* postdated */
589         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_postdated , tvb, 0, 0, (options[0]&0x02)?0x02000000:0);
590         if(options[0]&0x02){
591                 if(item){
592                         proto_item_append_text(item, " Postdated");
593                 }
594         }
595         /* renewable */
596         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_renewable , tvb, 0, 0, (options[1]&0x80)?0x00800000:0);
597         if(options[1]&0x80){
598                 if(item){
599                         proto_item_append_text(item, " Renewable");
600                 }
601         }
602         /* renewable_ok */
603         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_renewable_ok , tvb, 0, 0, (options[3]&0x10)?0x00000010:0);
604         if(options[3]&0x10){
605                 if(item){
606                         proto_item_append_text(item, " Renewable_Ok");
607                 }
608         }
609         /* enc_tkt_in_skey */
610         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_enc_tkt_in_skey , tvb, 0, 0, (options[3]&0x08)?0x00000008:0);
611         if(options[3]&0x08){
612                 if(item){
613                         proto_item_append_text(item, " Enc-Tkt-in-Skey");
614                 }
615         }
616         /* renew */
617         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_renew , tvb, 0, 0, (options[3]&0x02)?0x00000002:0);
618         if(options[3]&0x02){
619                 if(item){
620                         proto_item_append_text(item, " Renew");
621                 }
622         }
623         /* validate */
624         proto_tree_add_boolean(flags_tree, hf_krb_KDCOptions_validate , tvb, 0, 0, (options[3]&0x01)?0x00000001:0);
625         if(options[3]&0x01){
626                 if(item){
627                         proto_item_append_text(item, " Validate");
628                 }
629         }
630
631         return offset;
632 }
633
634 static int 
635 dissect_krb5_rtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
636 {
637         offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_rtime);
638         return offset;
639 }
640
641 static int 
642 dissect_krb5_ctime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
643 {
644         offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_ctime);
645         return offset;
646 }
647 static int
648 dissect_krb5_cusec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
649 {
650         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_cusec, NULL);
651         return offset;
652 }
653
654 static int 
655 dissect_krb5_stime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
656 {
657         offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_stime);
658         return offset;
659 }
660 static int
661 dissect_krb5_susec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
662 {
663         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_susec, NULL);
664         return offset;
665 }
666
667
668 static int
669 dissect_krb5_error_code(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
670 {
671         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_error_code, &krb5_error_code);
672         if(krb5_error_code && check_col(pinfo->cinfo, COL_INFO)) {
673                 col_add_fstr(pinfo->cinfo, COL_INFO, 
674                         "KRB Error: %s",
675                         val_to_str(krb5_error_code, krb5_error_codes,
676                         "Unknown error code %#x"));
677         }
678
679         return offset;
680 }
681
682
683 static int 
684 dissect_krb5_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
685 {
686         offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_till);
687         return offset;
688 }
689 static int 
690 dissect_krb5_from(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
691 {
692         offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_from);
693         return offset;
694 }
695
696
697
698 static int 
699 dissect_krb5_nonce(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
700 {
701         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_nonce, NULL);
702         return offset;
703 }
704
705
706 /*
707  *          etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
708  */
709 static int 
710 dissect_krb5_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
711 {
712         guint32 etype;
713
714         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &etype);
715         if(tree){
716                 proto_item_append_text(tree, " %s", 
717                         val_to_str(etype, krb5_encryption_types,
718                         "%#x"));
719         }
720         return offset;
721 }
722 static int
723 dissect_krb5_etype_sequence_of(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
724 {
725         offset=dissect_ber_sequence_of(pinfo, tree, tvb, offset, dissect_krb5_etype, hf_krb_etypes, ett_krb_etypes);
726
727         return offset;
728 }
729
730
731
732 /*
733  *  HostAddress ::=    SEQUENCE  {
734  *                     addr-type[0]             INTEGER,
735  *                     address[1]               OCTET STRING
736  *  }
737  */
738 static guint32 addr_type;
739 static int dissect_krb5_addr_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
740 {
741         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_addr_type, &addr_type);
742         return offset;
743 }
744 static int dissect_krb5_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
745 {
746         guint8 class;
747         gboolean pc;
748         guint32 tag;
749         guint32 len;
750         char address_str[256];
751         proto_item *it=NULL;
752
753         /* read header and len for the octet string */
754         offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
755         offset=dissect_ber_length(pinfo, tree, tvb, offset, &len);
756
757
758         address_str[0]=0;
759         address_str[255]=0;
760         switch(addr_type){
761         case KRB5_ADDR_IPv4:
762                 it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, FALSE);
763                 sprintf(address_str,"%d.%d.%d.%d",tvb_get_guint8(tvb, offset),tvb_get_guint8(tvb, offset+1),tvb_get_guint8(tvb, offset+2),tvb_get_guint8(tvb, offset+3));
764                 break;
765         case KRB5_ADDR_NETBIOS:
766                 {
767                 char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
768                 int netbios_name_type;
769
770                 netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name);
771                 snprintf(address_str, 255, "%s<%02x>", netbios_name, netbios_name_type); 
772                 it=proto_tree_add_string_format(tree, hf_krb_address_netbios, tvb, offset, 16, netbios_name, "NetBIOS Name: %s (%s)", address_str, netbios_name_type_descr(netbios_name_type));
773                 }
774                 break;
775         default:
776                 proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I dont know how to parse this type of address yet");
777
778         }
779
780         /* push it up two levels in the decode pane */
781         if(it){
782                 proto_item_append_text(it->parent, "  %s",address_str);
783                 proto_item_append_text(it->parent->parent, "  %s",address_str);
784         }
785
786         offset+=len;
787         return offset;
788 }
789 static ber_sequence HostAddress_sequence[] = {
790         { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
791         { BER_CLASS_CON, 1, 0, dissect_krb5_address },
792         { 0, 0, 0, NULL }
793 };
794 static int
795 dissect_krb5_HostAddress(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
796 {
797
798         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
799
800         return offset;
801 }
802
803 /*
804  *  HostAddresses ::=   SEQUENCE OF SEQUENCE {
805  *                      addr-type[0]             INTEGER,
806  *                      address[1]               OCTET STRING
807  *  }
808  *
809  */
810 static int
811 dissect_krb5_HostAddresses(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
812 {
813         offset=dissect_ber_sequence_of(pinfo, tree, tvb, offset, dissect_krb5_HostAddress, hf_krb_HostAddresses, ett_krb_HostAddresses);
814
815         return offset;
816 }
817
818
819
820 static int
821 dissect_krb5_msg_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
822 {
823         guint32 msgtype;
824
825         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_msg_type, &msgtype);
826
827         if (do_col_info & check_col(pinfo->cinfo, COL_INFO)) {
828                 col_add_str(pinfo->cinfo, COL_INFO, 
829                         val_to_str(msgtype, krb5_msg_types,
830                         "Unknown msg type %#x"));
831         }
832         do_col_info=FALSE;
833
834         return offset;
835 }
836
837
838
839 static int
840 dissect_krb5_pvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
841 {
842         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_pvno, NULL);
843
844         return offset;
845 }
846
847
848 /*
849  * PrincipalName ::=   SEQUENCE {
850  *                     name-type[0]     INTEGER,
851  *                     name-string[1]   SEQUENCE OF GeneralString
852  * }
853  */
854 static guint32 name_type;
855 static int 
856 dissect_krb5_name_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
857 {
858         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_name_type, &name_type);
859         if(tree){
860                 proto_item_append_text(tree, "  (%s):", 
861                         val_to_str(name_type, krb5_princ_types,
862                         "Unknown:%d"));
863         }
864         return offset;
865 }
866 static int 
867 dissect_krb5_name_string(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
868 {
869         char name_string[256];
870
871         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_name_string, name_string, 255);
872         if(tree){
873                 proto_item_append_text(tree, " %s", name_string);
874         }
875
876         return offset;
877 }
878 static int 
879 dissect_krb5_name_strings(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
880 {
881         offset=dissect_ber_sequence_of(pinfo, tree, tvb, offset, dissect_krb5_name_string, -1, -1);
882
883         return offset;
884 }
885 static ber_sequence PrincipalName_sequence[] = {
886         { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
887         { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
888         { 0, 0, 0, NULL }
889 };
890 static int
891 dissect_krb5_sname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
892 {
893
894         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
895
896         return offset;
897 }
898 static int
899 dissect_krb5_cname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
900 {
901
902         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_cname, ett_krb_cname);
903
904         return offset;
905 }
906
907
908 static int 
909 dissect_krb5_realm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
910 {
911         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_realm, NULL, 0);
912         return offset;
913 }
914
915 static int 
916 dissect_krb5_crealm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
917 {
918         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_crealm, NULL, 0);
919         return offset;
920 }
921
922
923
924 static int
925 dissect_krb5_PA_PAC_REQUEST_flag(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
926 {
927         offset=dissect_ber_boolean(pinfo, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag);
928         return offset;
929 }
930
931
932 static ber_sequence PA_PAC_REQUEST_sequence[] = {
933         { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
934         { 0, 0, 0, NULL }
935 };
936 static int
937 dissect_krb5_PA_PAC_REQUEST(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
938 {
939
940         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
941
942         return offset;
943 }
944
945
946
947
948 static int
949 dissect_krb5_kvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
950 {
951         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_kvno, NULL);
952
953         return offset;
954 }
955
956
957
958
959 static int
960 dissect_krb5_encrypted_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
961 {
962         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
963         return offset;
964 /*qqq*/
965 }
966 static ber_sequence PA_ENC_TIMESTAMP_sequence[] = {
967         { BER_CLASS_CON, 0, 0, 
968                 dissect_krb5_etype },
969         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
970                 dissect_krb5_kvno },
971         { BER_CLASS_CON, 2, 0,
972                 dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
973         { 0, 0, 0, NULL }
974 };
975 static int
976 dissect_krb5_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
977 {
978         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
979
980         return offset;
981 }
982
983
984
985 /*
986  * PA-DATA ::=        SEQUENCE {
987  *          padata-type[1]        INTEGER,
988  *          padata-value[2]       OCTET STRING,
989  *                        -- might be encoded AP-REQ
990  * }
991  */
992 guint32 krb_PA_DATA_type;
993 static int
994 dissect_krb5_PA_DATA_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
995 {
996         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
997
998         if(tree){
999                 proto_item_append_text(tree, " %s", 
1000                         val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
1001                         "Unknown:%d"));
1002         }
1003         return offset;
1004 }
1005 static int
1006 dissect_krb5_PA_DATA_value(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1007 {
1008         proto_tree *tree=parent_tree;
1009
1010         if(ber_last_created_item){
1011                 tree=proto_item_add_subtree(ber_last_created_item, ett_krb_PA_DATA_tree);
1012         }
1013
1014
1015         switch(krb_PA_DATA_type){
1016         case KRB5_PA_TGS_REQ:
1017                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
1018                 break;
1019         case KRB5_PA_PAC_REQUEST:
1020                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
1021                 break;
1022         case KRB5_PA_ENC_TIMESTAMP:
1023                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
1024                 break;
1025         default:
1026                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
1027         }
1028         return offset;
1029 /*qqq*/
1030 }
1031
1032 static ber_sequence PA_DATA_sequence[] = {
1033         { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
1034         { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
1035         { 0, 0, 0, NULL }
1036 };
1037 static int
1038 dissect_krb5_PA_DATA(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1039 {
1040         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PA_DATA_sequence, -1, -1);
1041
1042         return offset;
1043 }
1044
1045
1046
1047
1048 /*
1049  * padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
1050  *
1051  */
1052 static int
1053 dissect_krb5_padata(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1054 {
1055         offset=dissect_ber_sequence_of(pinfo, tree, tvb, offset, dissect_krb5_PA_DATA, hf_krb_padata, ett_krb_padata);
1056
1057         return offset;
1058 }
1059
1060
1061
1062
1063 /*
1064  * PRIV-BODY ::=   SEQUENCE {
1065  *  KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
1066  *               pvno[0]                   INTEGER,
1067  *               msg-type[1]               INTEGER,
1068  *               enc-part[3]               EncryptedData
1069  *  }
1070  */
1071 static int
1072 dissect_krb5_encrypted_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1073 {
1074         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_PRIV, NULL);
1075         return offset;
1076 }
1077 static ber_sequence ENC_PRIV_sequence[] = {
1078         { BER_CLASS_CON, 0, 0, 
1079                 dissect_krb5_etype },
1080         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1081                 dissect_krb5_kvno },
1082         { BER_CLASS_CON, 2, 0,
1083                 dissect_krb5_encrypted_PRIV },
1084         { 0, 0, 0, NULL }
1085 };
1086 static int
1087 dissect_krb5_ENC_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1088 {
1089         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, ENC_PRIV_sequence, hf_krb_ENC_PRIV, ett_krb_PRIV_enc);
1090         return offset;
1091 }
1092 static ber_sequence PRIV_BODY_sequence[] = {
1093         { BER_CLASS_CON, 0, 0, 
1094                 dissect_krb5_pvno },
1095         { BER_CLASS_CON, 1, 0, 
1096                 dissect_krb5_msg_type },
1097         { BER_CLASS_CON, 3, 0,
1098                 dissect_krb5_ENC_PRIV },
1099         { 0, 0, 0, NULL }
1100 };
1101 static int
1102 dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1103 {
1104
1105         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, PRIV_BODY_sequence, hf_krb_PRIV_BODY, ett_krb_PRIV);
1106
1107         return offset;
1108 }
1109
1110
1111 /*
1112  * KDC-REQ-BODY ::=   SEQUENCE {
1113  *           kdc-options[0]       KDCOptions,
1114  *           cname[1]             PrincipalName OPTIONAL,
1115  *                        -- Used only in AS-REQ
1116  *           realm[2]             Realm, -- Server's realm
1117  *                        -- Also client's in AS-REQ
1118  *           sname[3]             PrincipalName OPTIONAL,
1119  *           from[4]              KerberosTime OPTIONAL,
1120  *           till[5]              KerberosTime,
1121  *           rtime[6]             KerberosTime OPTIONAL,
1122  *           nonce[7]             INTEGER,
1123  *           etype[8]             SEQUENCE OF INTEGER, -- EncryptionType,
1124  *                        -- in preference order
1125  *           addresses[9]         HostAddresses OPTIONAL,
1126  *           enc-authorization-data[10]   EncryptedData OPTIONAL,
1127  *                        -- Encrypted AuthorizationData encoding
1128  *           additional-tickets[11]       SEQUENCE OF Ticket OPTIONAL
1129  * }
1130  *
1131  */
1132 static ber_sequence KDC_REQ_BODY_sequence[] = {
1133         { BER_CLASS_CON, 0, 0,
1134                 dissect_krb5_KDCOptions },
1135         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1136                 dissect_krb5_cname },
1137         { BER_CLASS_CON, 2, 0,
1138                 dissect_krb5_realm},
1139         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
1140                 dissect_krb5_sname },
1141         { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
1142                 dissect_krb5_from },
1143         { BER_CLASS_CON, 5, 0,
1144                 dissect_krb5_till },
1145         { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
1146                 dissect_krb5_rtime },
1147         { BER_CLASS_CON, 7, 0,
1148                 dissect_krb5_nonce },
1149         { BER_CLASS_CON, 8, 0,
1150                 dissect_krb5_etype_sequence_of },
1151         { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
1152                 dissect_krb5_HostAddresses },
1153 /* XXX [10] and [11] enc-authorization-data and additional-tickets should be added */
1154         { 0, 0, 0, NULL }
1155 };
1156 static int
1157 dissect_krb5_KDC_REQ_BODY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1158 {
1159
1160         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, KDC_REQ_BODY_sequence, hf_krb_KDC_REQ_BODY, ett_krb_request);
1161
1162         return offset;
1163 }
1164
1165
1166
1167 /*
1168  * KDC-REQ ::=        SEQUENCE {
1169  *          pvno[1]               INTEGER,
1170  *          msg-type[2]           INTEGER,
1171  *          padata[3]             SEQUENCE OF PA-DATA OPTIONAL,
1172  *          req-body[4]           KDC-REQ-BODY
1173  * }
1174  */
1175 static ber_sequence KDC_REQ_sequence[] = {
1176         { BER_CLASS_CON, 1, 0, 
1177                 dissect_krb5_pvno },
1178         { BER_CLASS_CON, 2, 0, 
1179                 dissect_krb5_msg_type },
1180         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
1181                 dissect_krb5_padata },
1182         { BER_CLASS_CON, 4, 0,
1183                 dissect_krb5_KDC_REQ_BODY },
1184         { 0, 0, 0, NULL }
1185 };
1186 static int
1187 dissect_krb5_KDC_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1188 {
1189         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, KDC_REQ_sequence, -1, -1);
1190
1191         return offset;
1192 }
1193
1194
1195 /*
1196  *  EncryptedData ::=   SEQUENCE {
1197  *                      etype[0]     INTEGER, -- EncryptionType
1198  *                      kvno[1]      INTEGER OPTIONAL,
1199  *                      cipher[2]    OCTET STRING -- ciphertext
1200  *  }
1201  */
1202 static int
1203 dissect_krb5_encrypted_authenticator_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1204 {
1205         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_authenticator_data, NULL);
1206         return offset;
1207 /*qqq*/
1208 }
1209 static ber_sequence encrypted_authenticator_sequence[] = {
1210         { BER_CLASS_CON, 0, 0, 
1211                 dissect_krb5_etype },
1212         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1213                 dissect_krb5_kvno },
1214         { BER_CLASS_CON, 2, 0,
1215                 dissect_krb5_encrypted_authenticator_data },
1216         { 0, 0, 0, NULL }
1217 };
1218 static int
1219 dissect_krb5_encrypted_authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1220 {
1221         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, encrypted_authenticator_sequence, hf_krb_authenticator_enc, ett_krb_authenticator_enc);
1222
1223         return offset;
1224 }
1225
1226
1227
1228
1229 static int 
1230 dissect_krb5_tkt_vno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1231 {
1232         offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_tkt_vno, NULL);
1233         return offset;
1234 }
1235
1236
1237
1238
1239 static int
1240 dissect_krb5_encrypted_Ticket_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1241 {
1242         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_Ticket_data, NULL);
1243         return offset;
1244 /*qqq*/
1245 }
1246 static ber_sequence encrypted_Ticket_sequence[] = {
1247         { BER_CLASS_CON, 0, 0, 
1248                 dissect_krb5_etype },
1249         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1250                 dissect_krb5_kvno },
1251         { BER_CLASS_CON, 2, 0,
1252                 dissect_krb5_encrypted_Ticket_data },
1253         { 0, 0, 0, NULL }
1254 };
1255 static int
1256 dissect_krb5_Ticket_encrypted(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1257 {
1258         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, encrypted_Ticket_sequence, hf_krb_ticket_enc, ett_krb_ticket_enc);
1259
1260         return offset;
1261 }
1262
1263 static ber_sequence Application_1_sequence[] = {
1264         { BER_CLASS_CON, 0, 0, 
1265                 dissect_krb5_tkt_vno },
1266         { BER_CLASS_CON, 1, 0, 
1267                 dissect_krb5_realm },
1268         { BER_CLASS_CON, 2, 0, 
1269                 dissect_krb5_sname },
1270         { BER_CLASS_CON, 3, 0, 
1271                 dissect_krb5_Ticket_encrypted },
1272         { 0, 0, 0, NULL }
1273 };
1274 static int
1275 dissect_krb5_Application_1(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1276 {
1277         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, Application_1_sequence, hf_krb_ticket, ett_krb_ticket);
1278
1279         return offset;
1280 }
1281
1282
1283
1284 static const ber_choice Ticket_choice[] = {
1285         { BER_CLASS_APP, 1,  
1286                 dissect_krb5_Application_1 },
1287         { 0, 0, NULL }
1288 };
1289 static int
1290 dissect_krb5_Ticket(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1291 {
1292         offset=dissect_ber_choice(pinfo, tree, tvb, offset, Ticket_choice, -1, -1);
1293
1294         return offset;
1295 }
1296
1297
1298
1299
1300 /*
1301  *  AP-REQ ::=      [APPLICATION 14] SEQUENCE {
1302  *                  pvno[0]                       INTEGER,
1303  *                  msg-type[1]                   INTEGER,
1304  *                  ap-options[2]                 APOptions,
1305  *                  ticket[3]                     Ticket,
1306  *                  authenticator[4]              EncryptedData
1307  *  }
1308  */
1309 static ber_sequence AP_REQ_sequence[] = {
1310         { BER_CLASS_CON, 0, 0, 
1311                 dissect_krb5_pvno },
1312         { BER_CLASS_CON, 1, 0, 
1313                 dissect_krb5_msg_type },
1314         { BER_CLASS_CON, 2, 0, 
1315                 dissect_krb5_APOptions },
1316         { BER_CLASS_CON, 3, 0, 
1317                 dissect_krb5_Ticket },
1318         { BER_CLASS_CON, 4, 0, 
1319                 dissect_krb5_encrypted_authenticator },
1320         { 0, 0, 0, NULL }
1321 };
1322 static int
1323 dissect_krb5_AP_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1324 {
1325         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, AP_REQ_sequence, -1, -1);
1326
1327         return offset;
1328 }
1329
1330
1331
1332
1333 static int
1334 dissect_krb5_encrypted_AP_REP_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1335 {
1336         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_AP_REP_data, NULL);
1337         return offset;
1338 /*qqq*/
1339 }
1340 static ber_sequence encrypted_AP_REP_sequence[] = {
1341         { BER_CLASS_CON, 0, 0, 
1342                 dissect_krb5_etype },
1343         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1344                 dissect_krb5_kvno },
1345         { BER_CLASS_CON, 2, 0,
1346                 dissect_krb5_encrypted_AP_REP_data },
1347         { 0, 0, 0, NULL }
1348 };
1349 static int
1350 dissect_krb5_encrypted_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1351 {
1352         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, encrypted_AP_REP_sequence, hf_krb_AP_REP_enc, ett_krb_AP_REP_enc);
1353
1354         return offset;
1355 }
1356
1357 /*
1358  *  AP-REP ::=         [APPLICATION 15] SEQUENCE {
1359  *             pvno[0]                   INTEGER,
1360  *             msg-type[1]               INTEGER,
1361  *             enc-part[2]               EncryptedData
1362  *  }
1363  */
1364 static ber_sequence AP_REP_sequence[] = {
1365         { BER_CLASS_CON, 0, 0, 
1366                 dissect_krb5_pvno },
1367         { BER_CLASS_CON, 1, 0, 
1368                 dissect_krb5_msg_type },
1369         { BER_CLASS_CON, 2, 0, 
1370                 dissect_krb5_encrypted_AP_REP },
1371         { 0, 0, 0, NULL }
1372 };
1373 static int
1374 dissect_krb5_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1375 {
1376         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, AP_REP_sequence, -1, -1);
1377
1378         return offset;
1379 }
1380
1381
1382
1383
1384
1385
1386
1387
1388 static int
1389 dissect_krb5_encrypted_KDC_REP_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1390 {
1391         offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_encrypted_KDC_REP_data, NULL);
1392         return offset;
1393 /*qqq*/
1394 }
1395 static ber_sequence encrypted_KDC_REP_sequence[] = {
1396         { BER_CLASS_CON, 0, 0, 
1397                 dissect_krb5_etype },
1398         { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
1399                 dissect_krb5_kvno },
1400         { BER_CLASS_CON, 2, 0,
1401                 dissect_krb5_encrypted_KDC_REP_data },
1402         { 0, 0, 0, NULL }
1403 };
1404 static int
1405 dissect_krb5_encrypted_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1406 {
1407         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, encrypted_KDC_REP_sequence, hf_krb_KDC_REP_enc, ett_krb_KDC_REP_enc);
1408
1409         return offset;
1410 }
1411
1412 /*
1413  *  KDC-REP ::=   SEQUENCE {
1414  *                pvno[0]                    INTEGER,
1415  *                msg-type[1]                INTEGER,
1416  *                padata[2]                  SEQUENCE OF PA-DATA OPTIONAL,
1417  *                crealm[3]                  Realm,
1418  *                cname[4]                   PrincipalName,
1419  *                ticket[5]                  Ticket,
1420  *                enc-part[6]                EncryptedData
1421  *  }
1422  */
1423 static ber_sequence KDC_REP_sequence[] = {
1424         { BER_CLASS_CON, 0, 0, 
1425                 dissect_krb5_pvno },
1426         { BER_CLASS_CON, 1, 0, 
1427                 dissect_krb5_msg_type },
1428         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
1429                 dissect_krb5_padata },
1430         { BER_CLASS_CON, 3, 0, 
1431                 dissect_krb5_crealm },
1432         { BER_CLASS_CON, 4, 0,
1433                 dissect_krb5_cname },
1434         { BER_CLASS_CON, 5, 0, 
1435                 dissect_krb5_Ticket },
1436         { BER_CLASS_CON, 6, 0, 
1437                 dissect_krb5_encrypted_KDC_REP },
1438         { 0, 0, 0, NULL }
1439 };
1440 static int
1441 dissect_krb5_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1442 {
1443         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, KDC_REP_sequence, -1, -1);
1444
1445         return offset;
1446 }
1447
1448
1449
1450
1451 static int 
1452 dissect_krb5_e_text(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1453 {
1454         offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_e_text, NULL, 0);
1455         return offset;
1456 }
1457 static int 
1458 dissect_krb5_e_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1459 {
1460         switch(krb5_error_code){
1461         case KRB5_ET_KRB5KDC_ERR_PREAUTH_REQUIRED:
1462                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_e_data, dissect_krb5_application_choice);
1463                 break;
1464         default:
1465                 offset=dissect_ber_octet_string(pinfo, tree, tvb, offset, hf_krb_e_data, NULL);
1466         }
1467         return offset;
1468 }
1469
1470
1471 /*
1472  *  KRB-ERROR ::=   [APPLICATION 30] SEQUENCE {
1473  *                  pvno[0]               INTEGER,
1474  *                  msg-type[1]           INTEGER,
1475  *                  ctime[2]              KerberosTime OPTIONAL,
1476  *                  cusec[3]              INTEGER OPTIONAL,
1477  *                  stime[4]              KerberosTime,
1478  *                  susec[5]              INTEGER,
1479  *                  error-code[6]         INTEGER,
1480  *                  crealm[7]             Realm OPTIONAL,
1481  *                  cname[8]              PrincipalName OPTIONAL,
1482  *                  realm[9]              Realm, -- Correct realm
1483  *                  sname[10]             PrincipalName, -- Correct name
1484  *                  e-text[11]            GeneralString OPTIONAL,
1485  *                  e-data[12]            OCTET STRING OPTIONAL
1486  *  }
1487  *
1488  *  e-data    This field contains additional data about the error for use
1489  *            by the application to help it recover from or handle the
1490  *            error.  If the errorcode is KDC_ERR_PREAUTH_REQUIRED, then
1491  *            the e-data field will contain an encoding of a sequence of
1492  *            padata fields, each corresponding to an acceptable pre-
1493  *            authentication method and optionally containing data for
1494  *            the method:
1495  */
1496 static ber_sequence ERROR_sequence[] = {
1497         { BER_CLASS_CON, 0, 0, 
1498                 dissect_krb5_pvno },
1499         { BER_CLASS_CON, 1, 0,
1500                 dissect_krb5_msg_type },
1501         { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
1502                 dissect_krb5_ctime },
1503         { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
1504                 dissect_krb5_cusec },
1505         { BER_CLASS_CON, 4, 0,
1506                 dissect_krb5_stime },
1507         { BER_CLASS_CON, 5, 0,
1508                 dissect_krb5_susec },
1509         { BER_CLASS_CON, 6, 0,
1510                 dissect_krb5_error_code },
1511         { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
1512                 dissect_krb5_crealm },
1513         { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
1514                 dissect_krb5_cname },
1515         { BER_CLASS_CON, 9, 0,
1516                 dissect_krb5_realm },
1517         { BER_CLASS_CON, 10, 0, 
1518                 dissect_krb5_sname },
1519         { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
1520                 dissect_krb5_e_text },
1521         { BER_CLASS_CON, 12, BER_FLAGS_OPTIONAL,
1522                 dissect_krb5_e_data },
1523         { 0, 0, 0, NULL }
1524 };
1525 static int
1526 dissect_krb5_ERROR(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
1527 {
1528         offset=dissect_ber_sequence(pinfo, tree, tvb, offset, ERROR_sequence, -1, -1);
1529
1530         return offset;
1531 }
1532
1533
1534
1535 static struct { char *set; char *unset; } bitval = { "Set", "Not set" };
1536
1537 static void dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo,
1538                                  proto_tree *tree);
1539 static void dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo,
1540                                  proto_tree *tree);
1541 static gint dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo,
1542                                         proto_tree *tree, int do_col_info,
1543                                         gboolean have_rm);
1544 static gint kerberos_rm_to_reclen(guint krb_rm);
1545 static void dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo,
1546                                 proto_tree *tree);
1547 static guint get_krb_pdu_len(tvbuff_t *tvb, int offset);
1548
1549
1550
1551 gint
1552 dissect_kerberos_main(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int do_col_info)
1553 {
1554     return (dissect_kerberos_common(tvb, pinfo, tree, do_col_info, FALSE));
1555 }
1556
1557 static void
1558 dissect_kerberos_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1559 {
1560     if (check_col(pinfo->cinfo, COL_PROTOCOL))
1561         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1562
1563     (void)dissect_kerberos_common(tvb, pinfo, tree, TRUE, FALSE);
1564 }
1565
1566 static gint
1567 kerberos_rm_to_reclen(guint krb_rm)
1568 {
1569     return (krb_rm & KRB_RM_RECLEN);
1570 }
1571
1572 static guint
1573 get_krb_pdu_len(tvbuff_t *tvb, int offset)
1574 {
1575     guint krb_rm;
1576     gint pdulen;
1577
1578     krb_rm = tvb_get_ntohl(tvb, offset);
1579     pdulen = kerberos_rm_to_reclen(krb_rm);
1580     return (pdulen + 4);
1581 }
1582
1583 static void
1584 dissect_kerberos_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1585 {
1586     pinfo->fragmented = TRUE;
1587     if (dissect_kerberos_common(tvb, pinfo, tree, TRUE, TRUE) < 0) {
1588         /*
1589          * The dissector failed to recognize this as a valid
1590          * Kerberos message.  Mark it as a continuation packet.
1591          */
1592         if (check_col(pinfo->cinfo, COL_INFO)) {
1593                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1594         }
1595     }
1596 }
1597
1598 static void
1599 dissect_kerberos_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1600 {
1601     if (check_col(pinfo->cinfo, COL_PROTOCOL))
1602         col_set_str(pinfo->cinfo, COL_PROTOCOL, "KRB5");
1603
1604     tcp_dissect_pdus(tvb, pinfo, tree, krb_desegment, 4, get_krb_pdu_len,
1605         dissect_kerberos_tcp_pdu);
1606 }
1607
1608 /*
1609  * Display the TCP record mark.
1610  */
1611 static void
1612 show_krb_recordmark(proto_tree *tree, tvbuff_t *tvb, gint start, guint32 krb_rm)
1613 {
1614     gint rec_len;
1615     proto_item *rm_item;
1616     proto_tree *rm_tree;
1617
1618     if (tree == NULL)
1619         return;
1620
1621     rec_len = kerberos_rm_to_reclen(krb_rm);
1622     rm_item = proto_tree_add_text(tree, tvb, start, 4,
1623         "Record Mark: %u %s", rec_len, plurality(rec_len, "byte", "bytes"));
1624     rm_tree = proto_item_add_subtree(rm_item, ett_krb_recordmark);
1625     proto_tree_add_boolean(rm_tree, hf_krb_rm_reserved, tvb, start, 4, krb_rm);
1626     proto_tree_add_uint(rm_tree, hf_krb_rm_reclen, tvb, start, 4, krb_rm);
1627 }
1628
1629
1630 static gint
1631 dissect_kerberos_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1632     int dci, gboolean have_rm)
1633 {
1634     int offset = 0;
1635     proto_tree *kerberos_tree = NULL;
1636     proto_item *item = NULL;
1637
1638     /* TCP record mark and length */
1639     guint32 krb_rm = 0;
1640     gint krb_reclen = 0;
1641
1642     do_col_info=dci;
1643
1644     if (tree) {
1645         item = proto_tree_add_item(tree, proto_kerberos, tvb, 0, -1, FALSE);
1646         kerberos_tree = proto_item_add_subtree(item, ett_krb_kerberos);
1647     }
1648
1649     if (have_rm) {
1650         krb_rm = tvb_get_ntohl(tvb, offset);
1651         krb_reclen = kerberos_rm_to_reclen(krb_rm);
1652         /*
1653          * What is a reasonable size limit?
1654          */
1655         if (krb_reclen > 10 * 1024 * 1024) {
1656             return (-1);
1657         }
1658         show_krb_recordmark(kerberos_tree, tvb, offset, krb_rm);
1659         offset += 4;
1660     }
1661
1662
1663     offset=dissect_ber_choice(pinfo, kerberos_tree, tvb, offset, kerberos_applications_choice, -1, -1);
1664     return offset;
1665 }
1666
1667
1668 void
1669 proto_register_kerberos(void)
1670 {
1671     static hf_register_info hf[] = {
1672         { &hf_krb_rm_reserved, {
1673             "Reserved", "kerberos.rm.reserved", FT_BOOLEAN, 32,
1674             &bitval, KRB_RM_RESERVED, "Record mark reserved bit", HFILL }},
1675         { &hf_krb_rm_reclen, {
1676             "Record Length", "kerberos.rm.length", FT_UINT32, BASE_DEC,
1677             NULL, KRB_RM_RECLEN, "Record length", HFILL }},
1678         { &hf_krb_etype, {
1679             "Encryption type", "kerberos.etype", FT_UINT32, BASE_DEC,
1680             VALS(krb5_encryption_types), 0, "Encryption Type", HFILL }},
1681         { &hf_krb_addr_type, {
1682             "Addr-type", "kerberos.addr_type", FT_UINT32, BASE_DEC,
1683             VALS(krb5_address_types), 0, "Address Type", HFILL }},
1684         { &hf_krb_name_type, {
1685             "Name-type", "kerberos.name_type", FT_UINT32, BASE_DEC,
1686             VALS(krb5_princ_types), 0, "Type of principal name", HFILL }},
1687         { &hf_krb_address_ip, {
1688             "IP Address", "kerberos.addr_ip", FT_IPv4, BASE_NONE,
1689             NULL, 0, "IP Address", HFILL }},
1690         { &hf_krb_address_netbios, {
1691             "NetBIOS Address", "kerberos.addr_nb", FT_STRING, BASE_NONE,
1692             NULL, 0, "NetBIOS Address and type", HFILL }},
1693         { &hf_krb_rtime, {
1694             "rtime", "kerberos.rtime", FT_STRING, BASE_NONE,
1695             NULL, 0, "Renew Until timestamp", HFILL }},
1696         { &hf_krb_ctime, {
1697             "ctime", "kerberos.ctime", FT_STRING, BASE_NONE,
1698             NULL, 0, "Current Time on the client host", HFILL }},
1699         { &hf_krb_cusec, {
1700             "cusec", "kerberos.cusec", FT_UINT32, BASE_DEC,
1701             NULL, 0, "micro second component of client time", HFILL }},
1702         { &hf_krb_stime, {
1703             "stime", "kerberos.stime", FT_STRING, BASE_NONE,
1704             NULL, 0, "Current Time on the server host", HFILL }},
1705         { &hf_krb_susec, {
1706             "susec", "kerberos.susec", FT_UINT32, BASE_DEC,
1707             NULL, 0, "micro second component of server time", HFILL }},
1708         { &hf_krb_error_code, {
1709             "error_code", "kerberos.error_code", FT_UINT32, BASE_DEC,
1710             VALS(krb5_error_codes), 0, "Kerberos error code", HFILL }},
1711         { &hf_krb_from, {
1712             "from", "kerberos.from", FT_STRING, BASE_NONE,
1713             NULL, 0, "From when the ticket is to be valid (postdating)", HFILL }},
1714         { &hf_krb_till, {
1715             "till", "kerberos.till", FT_STRING, BASE_NONE,
1716             NULL, 0, "When the ticket will expire", HFILL }},
1717         { &hf_krb_name_string, {
1718             "Name", "kerberos.name_string", FT_STRING, BASE_NONE,
1719             NULL, 0, "String component that is part of a PrincipalName", HFILL }},
1720         { &hf_krb_e_text, {
1721             "e-text", "kerberos.e_text", FT_STRING, BASE_NONE,
1722             NULL, 0, "Additional (human readable) error description", HFILL }},
1723         { &hf_krb_realm, {
1724             "Realm", "kerberos.realm", FT_STRING, BASE_NONE,
1725             NULL, 0, "Name of the Kerberos Realm", HFILL }},
1726         { &hf_krb_crealm, {
1727             "Client Realm", "kerberos.crealm", FT_STRING, BASE_NONE,
1728             NULL, 0, "Name of the Clients Kerberos Realm", HFILL }},
1729         { &hf_krb_msg_type, {
1730             "MSG Type", "kerberos.msg.type", FT_UINT32, BASE_DEC,
1731             VALS(krb5_msg_types), 0, "Kerberos Message Type", HFILL }},
1732         { &hf_krb_APOptions, {
1733             "APOptions", "kerberos.apoptions", FT_NONE, BASE_NONE,
1734             NULL, 0, "Kerberos APOptions bitstring", HFILL }},
1735         { &hf_krb_APOptions_use_session_key, {
1736             "Use Session Key", "kerberos.apoptions.use_session_key", FT_BOOLEAN, 32,
1737             TFS(&krb5_apoptions_use_session_key), 0x40000000, "", HFILL }},
1738         { &hf_krb_APOptions_mutual_required, {
1739             "Mutual required", "kerberos.apoptions.mutual_required", FT_BOOLEAN, 32,
1740             TFS(&krb5_apoptions_mutual_required), 0x20000000, "", HFILL }},
1741         { &hf_krb_KDCOptions, {
1742             "KDCOptions", "kerberos.kdcoptions", FT_NONE, BASE_NONE,
1743             NULL, 0, "Kerberos KDCOptions bitstring", HFILL }},
1744         { &hf_krb_KDC_REQ_BODY, {
1745             "KDC_REQ_BODY", "kerberos.kdc_req_body", FT_NONE, BASE_NONE,
1746             NULL, 0, "Kerberos KDC REQuest BODY", HFILL }},
1747         { &hf_krb_PRIV_BODY, {
1748             "PRIV_BODY", "kerberos.priv_body", FT_NONE, BASE_NONE,
1749             NULL, 0, "Kerberos PRIVate BODY", HFILL }},
1750         { &hf_krb_encrypted_PRIV, {
1751             "Encrypted PRIV", "kerberos.enc_priv", FT_NONE, BASE_NONE,
1752             NULL, 0, "Kerberos Encrypted PRIVate blob data", HFILL }},
1753         { &hf_krb_KDCOptions_forwardable, {
1754             "Forwardable", "kerberos.kdcoptions.forwardable", FT_BOOLEAN, 32,
1755             TFS(&krb5_kdcoptions_forwardable), 0x40000000, "Flag controlling whether the tickes are forwardable or not", HFILL }},
1756         { &hf_krb_KDCOptions_forwarded, {
1757             "Forwarded", "kerberos.kdcoptions.forwarded", FT_BOOLEAN, 32,
1758             TFS(&krb5_kdcoptions_forwarded), 0x20000000, "Has this ticket been forwarded?", HFILL }},
1759         { &hf_krb_KDCOptions_proxyable, {
1760             "Proxyable", "kerberos.kdcoptions.proxyable", FT_BOOLEAN, 32,
1761             TFS(&krb5_kdcoptions_proxyable), 0x10000000, "Flag controlling whether the tickes are proxyable or not", HFILL }},
1762         { &hf_krb_KDCOptions_proxy, {
1763             "Proxy", "kerberos.kdcoptions.proxy", FT_BOOLEAN, 32,
1764             TFS(&krb5_kdcoptions_proxy), 0x08000000, "Has this ticket been proxied?", HFILL }},
1765         { &hf_krb_KDCOptions_allow_postdate, {
1766             "Allow Postdate", "kerberos.kdcoptions.allow_postdate", FT_BOOLEAN, 32,
1767             TFS(&krb5_kdcoptions_allow_postdate), 0x04000000, "Flag controlling whether we allow postdated tickets or not", HFILL }},
1768         { &hf_krb_KDCOptions_postdated, {
1769             "Postdated", "kerberos.kdcoptions.postdated", FT_BOOLEAN, 32,
1770             TFS(&krb5_kdcoptions_postdated), 0x02000000, "Whether this ticket is postdated or not", HFILL }},
1771         { &hf_krb_KDCOptions_renewable, {
1772             "Renewable", "kerberos.kdcoptions.renewable", FT_BOOLEAN, 32,
1773             TFS(&krb5_kdcoptions_renewable), 0x00800000, "Whether this ticket is renewable or not", HFILL }},
1774         { &hf_krb_KDCOptions_renewable_ok, {
1775             "Renewable OK", "kerberos.kdcoptions.renewable_ok", FT_BOOLEAN, 32,
1776             TFS(&krb5_kdcoptions_renewable_ok), 0x00000010, "Whether we accept renewed tickets or not", HFILL }},
1777         { &hf_krb_KDCOptions_enc_tkt_in_skey, {
1778             "Enc-Tkt-in-Skey", "kerberos.kdcoptions.enc_tkt_in_skey", FT_BOOLEAN, 32,
1779             TFS(&krb5_kdcoptions_enc_tkt_in_skey), 0x00000008, "Whether the ticket is encrypted in the skey or not", HFILL }},
1780         { &hf_krb_KDCOptions_renew, {
1781             "Renew", "kerberos.kdcoptions.renew", FT_BOOLEAN, 32,
1782             TFS(&krb5_kdcoptions_renew), 0x00000002, "Is this a request to renew a ticket?", HFILL }},
1783         { &hf_krb_KDCOptions_validate, {
1784             "Validate", "kerberos.kdcoptions.validate", FT_BOOLEAN, 32,
1785             TFS(&krb5_kdcoptions_validate), 0x00000001, "Is this a request to validate a postdated ticket?", HFILL }},
1786         { &hf_krb_pvno, {
1787             "Pvno", "kerberos.pvno", FT_UINT32, BASE_DEC,
1788             NULL, 0, "Kerberos Protocol Version Number", HFILL }},
1789         { &hf_krb_kvno, {
1790             "Kvno", "kerberos.kvno", FT_UINT32, BASE_DEC,
1791             NULL, 0, "Version Number for the encryption Key", HFILL }},
1792         { &hf_krb_encrypted_authenticator_data, {
1793             "Authenticator data", "kerberos.authenticator.data", FT_BYTES, BASE_HEX,
1794             NULL, 0, "Data content of an encrypted authenticator", HFILL }},
1795         { &hf_krb_encrypted_PA_ENC_TIMESTAMP, {
1796             "enc PA_ENC_TIMESTAMP", "kerberos.PA_ENC_TIMESTAMP.encrypted", FT_BYTES, BASE_HEX,
1797             NULL, 0, "Encrypted PA-ENC-TIMESTAMP blob", HFILL }},
1798         { &hf_krb_ENC_PRIV, {
1799             "enc PRIV", "kerberos.ENC_PRIV", FT_BYTES, BASE_HEX,
1800             NULL, 0, "Encrypted PRIV blob", HFILL }},
1801         { &hf_krb_encrypted_Ticket_data, {
1802             "enc-part", "kerberos.ticket.data", FT_BYTES, BASE_HEX,
1803             NULL, 0, "The encrypted part of a ticket", HFILL }},
1804         { &hf_krb_encrypted_AP_REP_data, {
1805             "enc-part", "kerberos.aprep.data", FT_BYTES, BASE_HEX,
1806             NULL, 0, "The encrypted part of AP-REP", HFILL }},
1807         { &hf_krb_encrypted_KDC_REP_data, {
1808             "enc-part", "kerberos.kdcrep.data", FT_BYTES, BASE_HEX,
1809             NULL, 0, "The encrypted part of KDC-REP", HFILL }},
1810         { &hf_krb_PA_DATA_value, {
1811             "Value", "kerberos.padata.value", FT_BYTES, BASE_HEX,
1812             NULL, 0, "Content of the PADATA blob", HFILL }},
1813         { &hf_krb_PA_DATA_type, {
1814             "Type", "kerberos.padata.type", FT_UINT32, BASE_DEC,
1815             VALS(krb5_preauthentication_types), 0, "Type of preauthentication data", HFILL }},
1816         { &hf_krb_nonce, {
1817             "Nonce", "kerberos.nonce", FT_UINT32, BASE_DEC,
1818             NULL, 0, "Kerberos Nonce random number", HFILL }},
1819         { &hf_krb_tkt_vno, {
1820             "Tkt-vno", "kerberos.tkt_vno", FT_UINT32, BASE_DEC,
1821             NULL, 0, "Version number for the Ticket format", HFILL }},
1822         { &hf_krb_HostAddress, {
1823             "HostAddress", "kerberos.hostaddress", FT_NONE, BASE_DEC,
1824             NULL, 0, "This is a Kerberos HostAddress sequence", HFILL }},
1825         { &hf_krb_HostAddresses, {
1826             "HostAddresses", "kerberos.hostaddresses", FT_NONE, BASE_DEC,
1827             NULL, 0, "This is a list of Kerberos HostAddress sequences", HFILL }},
1828         { &hf_krb_etypes, {
1829             "Encryption Types", "kerberos.etypes", FT_NONE, BASE_DEC,
1830             NULL, 0, "This is a list of Kerberos encryption types", HFILL }},
1831         { &hf_krb_sname, {
1832             "Server Name", "kerberos.sname", FT_NONE, BASE_DEC,
1833             NULL, 0, "This is the name part server's identity", HFILL }},
1834         { &hf_krb_cname, {
1835             "Client Name", "kerberos.cname", FT_NONE, BASE_DEC,
1836             NULL, 0, "The name part of the client principal identifier", HFILL }},
1837         { &hf_krb_authenticator_enc, {
1838             "Authenticator", "kerberos.authenticator", FT_NONE, BASE_DEC,
1839             NULL, 0, "Encrypted authenticator blob", HFILL }},
1840         { &hf_krb_ticket_enc, {
1841             "enc-part", "kerberos.ticket.enc_part", FT_NONE, BASE_DEC,
1842             NULL, 0, "The structure holding the encrypted part of a ticket", HFILL }},
1843         { &hf_krb_AP_REP_enc, {
1844             "enc-part", "kerberos.aprep.enc_part", FT_NONE, BASE_DEC,
1845             NULL, 0, "The structure holding the encrypted part of AP-REP", HFILL }},
1846         { &hf_krb_KDC_REP_enc, {
1847             "enc-part", "kerberos.kdcrep.enc_part", FT_NONE, BASE_DEC,
1848             NULL, 0, "The structure holding the encrypted part of KDC-REP", HFILL }},
1849         { &hf_krb_e_data, {
1850             "e-data", "kerberos.e_data", FT_NONE, BASE_DEC,
1851             NULL, 0, "The e-data blob", HFILL }},
1852         { &hf_krb_padata, {
1853             "padata", "kerberos.padata", FT_NONE, BASE_DEC,
1854             NULL, 0, "Sequence of preauthentication data", HFILL }},
1855         { &hf_krb_ticket, {
1856             "Ticket", "kerberos.ticket", FT_NONE, BASE_DEC,
1857             NULL, 0, "This is a Kerberos Ticket", HFILL }},
1858         { &hf_krb_PA_PAC_REQUEST_flag, {
1859             "PAC Request", "kerberos.pac_request.flag", FT_UINT32, BASE_DEC,
1860             NULL, 0, "This is a MS PAC Request Flag", HFILL }},
1861     };
1862
1863     static gint *ett[] = {
1864         &ett_krb_kerberos,
1865         &ett_krb_KDC_REP_enc,
1866         &ett_krb_sname,
1867         &ett_krb_cname,
1868         &ett_krb_AP_REP_enc,
1869         &ett_krb_padata,
1870         &ett_krb_etypes,
1871         &ett_krb_PA_DATA_tree,
1872         &ett_krb_HostAddress,
1873         &ett_krb_HostAddresses,
1874         &ett_krb_authenticator_enc,
1875         &ett_krb_AP_Options,
1876         &ett_krb_KDC_Options,
1877         &ett_krb_request,
1878         &ett_krb_recordmark,
1879         &ett_krb_ticket,
1880         &ett_krb_ticket_enc,
1881         &ett_krb_PRIV,
1882         &ett_krb_PRIV_enc,
1883     };
1884     module_t *krb_module;
1885
1886     proto_kerberos = proto_register_protocol("Kerberos", "KRB5", "kerberos");
1887     proto_register_field_array(proto_kerberos, hf, array_length(hf));
1888     proto_register_subtree_array(ett, array_length(ett));
1889
1890     /* Register preferences */
1891     krb_module = prefs_register_protocol(proto_kerberos, NULL);
1892     prefs_register_bool_preference(krb_module, "desegment",
1893         "Desegment Kerberos over TCP messages",
1894         "Whether the dissector should desegment "
1895         "multi-segment Kerberos messages", &krb_desegment);
1896 }
1897
1898 void
1899 proto_reg_handoff_kerberos(void)
1900 {
1901     dissector_handle_t kerberos_handle_udp;
1902     dissector_handle_t kerberos_handle_tcp;
1903
1904     kerberos_handle_udp = create_dissector_handle(dissect_kerberos_udp,
1905         proto_kerberos);
1906     kerberos_handle_tcp = create_dissector_handle(dissect_kerberos_tcp,
1907         proto_kerberos);
1908     dissector_add("udp.port", UDP_PORT_KERBEROS, kerberos_handle_udp);
1909     dissector_add("tcp.port", TCP_PORT_KERBEROS, kerberos_handle_tcp);
1910
1911 }
1912
1913 /*
1914
1915   MISC definitions from RFC1510:
1916
1917    Realm ::=           GeneralString
1918
1919    KerberosTime ::=   GeneralizedTime
1920
1921    AuthorizationData ::=   SEQUENCE OF SEQUENCE {
1922                            ad-type[0]               INTEGER,
1923                            ad-data[1]               OCTET STRING
1924    }
1925                    APOptions ::=   BIT STRING {
1926                                    reserved(0),
1927                                    use-session-key(1),
1928                                    mutual-required(2)
1929                    }
1930
1931
1932                    TicketFlags ::=   BIT STRING {
1933                                      reserved(0),
1934                                      forwardable(1),
1935                                      forwarded(2),
1936                                      proxiable(3),
1937                                      proxy(4),
1938                                      may-postdate(5),
1939                                      postdated(6),
1940                                      invalid(7),
1941                                      renewable(8),
1942                                      initial(9),
1943                                      pre-authent(10),
1944                                      hw-authent(11)
1945                    }
1946
1947                   KDCOptions ::=   BIT STRING {
1948                                    reserved(0),
1949                                    forwardable(1),
1950                                    forwarded(2),
1951                                    proxiable(3),
1952                                    proxy(4),
1953                                    allow-postdate(5),
1954                                    postdated(6),
1955                                    unused7(7),
1956                                    renewable(8),
1957                                    unused9(9),
1958                                    unused10(10),
1959                                    unused11(11),
1960                                    renewable-ok(27),
1961                                    enc-tkt-in-skey(28),
1962                                    renew(30),
1963                                    validate(31)
1964                   }
1965
1966
1967             LastReq ::=   SEQUENCE OF SEQUENCE {
1968                           lr-type[0]               INTEGER,
1969                           lr-value[1]              KerberosTime
1970             }
1971
1972    Ticket ::=                    [APPLICATION 1] SEQUENCE {
1973                                  tkt-vno[0]                   INTEGER,
1974                                  realm[1]                     Realm,
1975                                  sname[2]                     PrincipalName,
1976                                  enc-part[3]                  EncryptedData
1977    }
1978
1979   -- Encrypted part of ticket
1980   EncTicketPart ::=     [APPLICATION 3] SEQUENCE {
1981                         flags[0]             TicketFlags,
1982                         key[1]               EncryptionKey,
1983                         crealm[2]            Realm,
1984                         cname[3]             PrincipalName,
1985                         transited[4]         TransitedEncoding,
1986                         authtime[5]          KerberosTime,
1987                         starttime[6]         KerberosTime OPTIONAL,
1988                         endtime[7]           KerberosTime,
1989                         renew-till[8]        KerberosTime OPTIONAL,
1990                         caddr[9]             HostAddresses OPTIONAL,
1991                         authorization-data[10]   AuthorizationData OPTIONAL
1992   }
1993
1994   -- encoded Transited field
1995   TransitedEncoding ::=         SEQUENCE {
1996                                 tr-type[0]  INTEGER, -- must be registered
1997                                 contents[1]          OCTET STRING
1998   }
1999
2000   -- Unencrypted authenticator
2001   Authenticator ::=    [APPLICATION 2] SEQUENCE    {
2002                  authenticator-vno[0]          INTEGER,
2003                  crealm[1]                     Realm,
2004                  cname[2]                      PrincipalName,
2005                  cksum[3]                      Checksum OPTIONAL,
2006                  cusec[4]                      INTEGER,
2007                  ctime[5]                      KerberosTime,
2008                  subkey[6]                     EncryptionKey OPTIONAL,
2009                  seq-number[7]                 INTEGER OPTIONAL,
2010                  authorization-data[8]         AuthorizationData OPTIONAL
2011   }
2012
2013   PA-DATA ::=        SEQUENCE {
2014            padata-type[1]        INTEGER,
2015            padata-value[2]       OCTET STRING,
2016                          -- might be encoded AP-REQ
2017   }
2018
2019    padata-type     ::= PA-ENC-TIMESTAMP
2020    padata-value    ::= EncryptedData -- PA-ENC-TS-ENC
2021
2022    PA-ENC-TS-ENC   ::= SEQUENCE {
2023            patimestamp[0]               KerberosTime, -- client's time
2024            pausec[1]                    INTEGER OPTIONAL
2025    }
2026
2027    EncASRepPart ::=    [APPLICATION 25[25]] EncKDCRepPart
2028    EncTGSRepPart ::=   [APPLICATION 26] EncKDCRepPart
2029
2030    EncKDCRepPart ::=   SEQUENCE {
2031                key[0]                       EncryptionKey,
2032                last-req[1]                  LastReq,
2033                nonce[2]                     INTEGER,
2034                key-expiration[3]            KerberosTime OPTIONAL,
2035                flags[4]                     TicketFlags,
2036                authtime[5]                  KerberosTime,
2037                starttime[6]                 KerberosTime OPTIONAL,
2038                endtime[7]                   KerberosTime,
2039                renew-till[8]                KerberosTime OPTIONAL,
2040                srealm[9]                    Realm,
2041                sname[10]                    PrincipalName,
2042                caddr[11]                    HostAddresses OPTIONAL
2043    }
2044
2045    APOptions ::=   BIT STRING {
2046                    reserved(0),
2047                    use-session-key(1),
2048                    mutual-required(2)
2049    }
2050
2051    EncAPRepPart ::=   [APPLICATION 27]     SEQUENCE {
2052               ctime[0]                  KerberosTime,
2053               cusec[1]                  INTEGER,
2054               subkey[2]                 EncryptionKey OPTIONAL,
2055               seq-number[3]             INTEGER OPTIONAL
2056    }
2057
2058    KRB-SAFE ::=        [APPLICATION 20] SEQUENCE {
2059                pvno[0]               INTEGER,
2060                msg-type[1]           INTEGER,
2061                safe-body[2]          KRB-SAFE-BODY,
2062                cksum[3]              Checksum
2063    }
2064
2065    KRB-SAFE-BODY ::=   SEQUENCE {
2066                user-data[0]          OCTET STRING,
2067                timestamp[1]          KerberosTime OPTIONAL,
2068                usec[2]               INTEGER OPTIONAL,
2069                seq-number[3]         INTEGER OPTIONAL,
2070                s-address[4]          HostAddress,
2071                r-address[5]          HostAddress OPTIONAL
2072    }
2073
2074    KRB-PRIV ::=         [APPLICATION 21] SEQUENCE {
2075                 pvno[0]                   INTEGER,
2076                 msg-type[1]               INTEGER,
2077                 enc-part[3]               EncryptedData
2078    }
2079
2080    EncKrbPrivPart ::=   [APPLICATION 28] SEQUENCE {
2081                 user-data[0]              OCTET STRING,
2082                 timestamp[1]              KerberosTime OPTIONAL,
2083                 usec[2]                   INTEGER OPTIONAL,
2084                 seq-number[3]             INTEGER OPTIONAL,
2085                 s-address[4]              HostAddress, -- sender's addr
2086                 r-address[5]              HostAddress OPTIONAL
2087                                                       -- recip's addr
2088    }
2089
2090    KRB-CRED         ::= [APPLICATION 22]   SEQUENCE {
2091                     pvno[0]                INTEGER,
2092                     msg-type[1]            INTEGER, -- KRB_CRED
2093                     tickets[2]             SEQUENCE OF Ticket,
2094                     enc-part[3]            EncryptedData
2095    }
2096
2097    EncKrbCredPart   ::= [APPLICATION 29]   SEQUENCE {
2098                     ticket-info[0]         SEQUENCE OF KrbCredInfo,
2099                     nonce[1]               INTEGER OPTIONAL,
2100                     timestamp[2]           KerberosTime OPTIONAL,
2101                     usec[3]                INTEGER OPTIONAL,
2102                     s-address[4]           HostAddress OPTIONAL,
2103                     r-address[5]           HostAddress OPTIONAL
2104    }
2105
2106    KrbCredInfo      ::=                    SEQUENCE {
2107                     key[0]                 EncryptionKey,
2108                     prealm[1]              Realm OPTIONAL,
2109                     pname[2]               PrincipalName OPTIONAL,
2110                     flags[3]               TicketFlags OPTIONAL,
2111                     authtime[4]            KerberosTime OPTIONAL,
2112                     starttime[5]           KerberosTime OPTIONAL,
2113                     endtime[6]             KerberosTime OPTIONAL
2114                     renew-till[7]          KerberosTime OPTIONAL,
2115                     srealm[8]              Realm OPTIONAL,
2116                     sname[9]               PrincipalName OPTIONAL,
2117                     caddr[10]              HostAddresses OPTIONAL
2118    }
2119
2120       METHOD-DATA ::=    SEQUENCE of PA-DATA
2121
2122    If the error-code is KRB_AP_ERR_METHOD, then the e-data field will
2123    contain an encoding of the following sequence:
2124
2125       METHOD-DATA ::=    SEQUENCE {
2126                          method-type[0]   INTEGER,
2127                          method-data[1]   OCTET STRING OPTIONAL
2128       }
2129
2130       EncryptionKey ::=   SEQUENCE {
2131                          keytype[0]    INTEGER,
2132                          keyvalue[1]   OCTET STRING
2133       }
2134
2135       Checksum ::=   SEQUENCE {
2136                          cksumtype[0]   INTEGER,
2137                          checksum[1]    OCTET STRING
2138       }
2139
2140 */