+static const value_string krb5_msg_types[] = {
+ { KRB5_MSG_AUTHENTICATOR, "Authenticator" },
+ { KRB5_MSG_ENC_TICKET_PART, "EncTicketPart" },
+ { KRB5_MSG_TGS_REQ, "TGS-REQ" },
+ { KRB5_MSG_TGS_REP, "TGS-REP" },
+ { KRB5_MSG_AS_REQ, "AS-REQ" },
+ { KRB5_MSG_AS_REP, "AS-REP" },
+ { KRB5_MSG_AP_REQ, "AP-REQ" },
+ { KRB5_MSG_AP_REP, "AP-REP" },
+ { KRB5_MSG_SAFE, "KRB-SAFE" },
+ { KRB5_MSG_PRIV, "KRB-PRIV" },
+ { KRB5_MSG_CRED, "KRB-CRED" },
+ { KRB5_MSG_ENC_AS_REP_PART, "EncASRepPart" },
+ { KRB5_MSG_ENC_TGS_REP_PART, "EncTGSRepPart" },
+ { KRB5_MSG_ENC_AP_REP_PART, "EncAPRepPart" },
+ { KRB5_MSG_ERROR, "KRB-ERROR" },
+ { 0, NULL },
+};
+
+
+
+
+static int dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_Authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_EncTicketPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_EncAPRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_EncKDCRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_KDC_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_KDC_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_AP_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_AP_REP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_SAFE(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+static int dissect_krb5_ERROR(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset);
+
+static const ber_choice kerberos_applications_choice[] = {
+ { KRB5_MSG_AUTHENTICATOR, BER_CLASS_APP, KRB5_MSG_AUTHENTICATOR, 0, dissect_krb5_Authenticator },
+ { KRB5_MSG_ENC_TICKET_PART, BER_CLASS_APP, KRB5_MSG_ENC_TICKET_PART, 0, dissect_krb5_EncTicketPart },
+ { KRB5_MSG_AS_REQ, BER_CLASS_APP, KRB5_MSG_AS_REQ, 0, dissect_krb5_KDC_REQ },
+ { KRB5_MSG_AS_REP, BER_CLASS_APP, KRB5_MSG_AS_REP, 0, dissect_krb5_KDC_REP },
+ { KRB5_MSG_TGS_REQ, BER_CLASS_APP, KRB5_MSG_TGS_REQ, 0, dissect_krb5_KDC_REQ },
+ { KRB5_MSG_TGS_REP, BER_CLASS_APP, KRB5_MSG_TGS_REP, 0, dissect_krb5_KDC_REP },
+ { KRB5_MSG_AP_REQ, BER_CLASS_APP, KRB5_MSG_AP_REQ, 0, dissect_krb5_AP_REQ },
+ { KRB5_MSG_AP_REP, BER_CLASS_APP, KRB5_MSG_AP_REP, 0, dissect_krb5_AP_REP },
+ { KRB5_MSG_ENC_AS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
+ { KRB5_MSG_ENC_TGS_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_TGS_REP_PART, 0, dissect_krb5_EncKDCRepPart },
+ { KRB5_MSG_ENC_AP_REP_PART, BER_CLASS_APP, KRB5_MSG_ENC_AP_REP_PART, 0, dissect_krb5_EncAPRepPart },
+ { KRB5_MSG_SAFE, BER_CLASS_APP, KRB5_MSG_SAFE, 0, dissect_krb5_SAFE },
+ { KRB5_MSG_PRIV, BER_CLASS_APP, KRB5_MSG_PRIV, 0, dissect_krb5_PRIV },
+ { KRB5_MSG_ERROR, BER_CLASS_APP, KRB5_MSG_ERROR, 0, dissect_krb5_ERROR },
+ { 0, 0, 0, 0, NULL }
+};
+
+
+static int
+dissect_krb5_application_choice(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_choice(pinfo, tree, tvb, offset, kerberos_applications_choice, -1, -1);
+ return offset;
+}
+
+
+static const true_false_string krb5_apoptions_use_session_key = {
+ "USE SESSION KEY to encrypt the ticket",
+ "Do NOT use the session key to encrypt the ticket"
+};
+static const true_false_string krb5_apoptions_mutual_required = {
+ "MUTUAL authentication is REQUIRED",
+ "Mutual authentication is NOT required"
+};
+
+static int *APOptions_bits[] = {
+ &hf_krb_APOptions_use_session_key,
+ &hf_krb_APOptions_mutual_required,
+ NULL
+};
+static int
+dissect_krb5_APOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, APOptions_bits, hf_krb_APOptions, ett_krb_AP_Options, NULL);
+ return offset;
+}
+
+
+
+static const true_false_string krb5_kdcoptions_forwardable = {
+ "FORWARDABLE tickets are allowed/requested",
+ "Do NOT use forwardable tickets"
+};
+static const true_false_string krb5_kdcoptions_forwarded = {
+ "This ticket has been FORWARDED",
+ "This is NOT a forwarded ticket"
+};
+static const true_false_string krb5_kdcoptions_proxyable = {
+ "PROXIABLE tickets are allowed/requested",
+ "Do NOT use proxiable tickets"
+};
+static const true_false_string krb5_kdcoptions_proxy = {
+ "This is a PROXY ticket",
+ "This ticket has NOT been proxied"
+};
+static const true_false_string krb5_kdcoptions_allow_postdate = {
+ "We allow the ticket to be POSTDATED",
+ "We do NOT allow the ticket to be postdated"
+};
+static const true_false_string krb5_kdcoptions_postdated = {
+ "This ticket is POSTDATED",
+ "This ticket is NOT postdated"
+};
+static const true_false_string krb5_kdcoptions_renewable = {
+ "This ticket is RENEWABLE",
+ "This ticket is NOT renewable"
+};
+static const true_false_string krb5_kdcoptions_canonicalize = {
+ "This is a request for a CANONICALIZED ticket",
+ "This is NOT a canonicalized ticket request"
+};
+static const true_false_string krb5_kdcoptions_disable_transited_check = {
+ "Transited checking is DISABLED",
+ "Transited checking is NOT disabled"
+};
+static const true_false_string krb5_kdcoptions_renewable_ok = {
+ "We accept RENEWED tickets",
+ "We do NOT accept renewed tickets"
+};
+static const true_false_string krb5_kdcoptions_enc_tkt_in_skey = {
+ "ENCrypt TKT in SKEY",
+ "Do NOT encrypt the tkt inside the skey"
+};
+static const true_false_string krb5_kdcoptions_renew = {
+ "This is a request to RENEW a ticket",
+ "This is NOT a request to renew a ticket"
+};
+static const true_false_string krb5_kdcoptions_validate = {
+ "This is a request to VALIDATE a postdated ticket",
+ "This is NOT a request to validate a postdated ticket"
+};
+
+static int* KDCOptions_bits[] = {
+ &hf_krb_KDCOptions_forwardable,
+ &hf_krb_KDCOptions_forwarded,
+ &hf_krb_KDCOptions_proxyable,
+ &hf_krb_KDCOptions_proxy,
+ &hf_krb_KDCOptions_allow_postdate,
+ &hf_krb_KDCOptions_postdated,
+ &hf_krb_KDCOptions_renewable,
+ &hf_krb_KDCOptions_opt_hardware_auth,
+ &hf_krb_KDCOptions_canonicalize,
+ &hf_krb_KDCOptions_disable_transited_check,
+ &hf_krb_KDCOptions_renewable_ok,
+ &hf_krb_KDCOptions_enc_tkt_in_skey,
+ &hf_krb_KDCOptions_renew,
+ &hf_krb_KDCOptions_validate,
+ NULL
+};
+
+static int
+dissect_krb5_KDCOptions(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, KDCOptions_bits, hf_krb_KDCOptions, ett_krb_KDC_Options, NULL);
+ return offset;
+}
+
+static int
+dissect_krb5_rtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_rtime);
+ return offset;
+}
+
+static int
+dissect_krb5_ctime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_ctime);
+ return offset;
+}
+static int
+dissect_krb5_cusec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_cusec, NULL);
+ return offset;
+}
+
+static int
+dissect_krb5_stime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_stime);
+ return offset;
+}
+static int
+dissect_krb5_susec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_susec, NULL);
+ return offset;
+}
+
+
+static int
+dissect_krb5_error_code(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_error_code, &krb5_errorcode);
+ if(krb5_errorcode && check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "KRB Error: %s",
+ val_to_str(krb5_errorcode, krb5_error_codes,
+ "Unknown error code %#x"));
+ }
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_till);
+ return offset;
+}
+static int
+dissect_krb5_from(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_from);
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_nonce(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_nonce, NULL);
+ return offset;
+}
+
+
+/*
+ * etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
+ */
+static int
+dissect_krb5_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 etype;
+
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &etype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(etype, krb5_encryption_types,
+ "%d"));
+ }
+ return offset;
+}
+static ber_sequence etype_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_krb5_etype },
+};
+static int
+dissect_krb5_etype_sequence_of(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, etype_sequence_of, hf_krb_etypes, ett_krb_etypes);
+
+ return offset;
+}
+static guint32 authenticator_etype;
+static int
+dissect_krb5_authenticator_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &authenticator_etype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(authenticator_etype, krb5_encryption_types,
+ "%#x"));
+ }
+ return offset;
+}
+static guint32 Ticket_etype;
+static int
+dissect_krb5_Ticket_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &Ticket_etype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(Ticket_etype, krb5_encryption_types,
+ "%#x"));
+ }
+ return offset;
+}
+static guint32 AP_REP_etype;
+static int
+dissect_krb5_AP_REP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &AP_REP_etype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(AP_REP_etype, krb5_encryption_types,
+ "%#x"));
+ }
+ return offset;
+}
+static guint32 PA_ENC_TIMESTAMP_etype;
+static int
+dissect_krb5_PA_ENC_TIMESTAMP_etype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_etype, &PA_ENC_TIMESTAMP_etype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(PA_ENC_TIMESTAMP_etype, krb5_encryption_types,
+ "%#x"));
+ }
+ return offset;
+}
+
+
+/*
+ * HostAddress ::= SEQUENCE {
+ * addr-type[0] INTEGER,
+ * address[1] OCTET STRING
+ * }
+ */
+static guint32 addr_type;
+static int dissect_krb5_addr_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_addr_type, &addr_type);
+ return offset;
+}
+static int dissect_krb5_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint8 class;
+ gboolean pc;
+ guint32 tag;
+ guint32 len;
+ char address_str[256];
+ proto_item *it=NULL;
+
+ /* read header and len for the octet string */
+ offset=dissect_ber_identifier(pinfo, tree, tvb, offset, &class, &pc, &tag);
+ offset=dissect_ber_length(pinfo, tree, tvb, offset, &len, NULL);
+
+
+ address_str[0]=0;
+ address_str[255]=0;
+ switch(addr_type){
+ case KRB5_ADDR_IPv4:
+ it=proto_tree_add_item(tree, hf_krb_address_ip, tvb, offset, 4, FALSE);
+ 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));
+ break;
+ case KRB5_ADDR_NETBIOS:
+ {
+ char netbios_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
+ int netbios_name_type;
+
+ netbios_name_type = process_netbios_name(tvb_get_ptr(tvb, offset, 16), netbios_name);
+ snprintf(address_str, 255, "%s<%02x>", netbios_name, netbios_name_type);
+ 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));
+ }
+ break;
+ default:
+ proto_tree_add_text(tree, tvb, offset, len, "KRB Address: I dont know how to parse this type of address yet");
+
+ }
+
+ /* push it up two levels in the decode pane */
+ if(it){
+ proto_item_append_text(proto_item_get_parent(it), " %s",address_str);
+ proto_item_append_text(proto_item_get_parent_nth(it, 2), " %s",address_str);
+ }
+
+ offset+=len;
+ return offset;
+}
+static ber_sequence HostAddress_sequence[] = {
+ { BER_CLASS_CON, 0, 0, dissect_krb5_addr_type },
+ { BER_CLASS_CON, 1, 0, dissect_krb5_address },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_HostAddress(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, HostAddress_sequence, hf_krb_HostAddress, ett_krb_HostAddress);
+
+ return offset;
+}
+static int
+dissect_krb5_s_address(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, HostAddress_sequence, hf_krb_s_address, ett_krb_s_address);
+
+ return offset;
+}
+
+/*
+ * HostAddresses ::= SEQUENCE OF SEQUENCE {
+ * addr-type[0] INTEGER,
+ * address[1] OCTET STRING
+ * }
+ *
+ */
+static ber_sequence HostAddresses_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_HostAddress },
+};
+static int
+dissect_krb5_HostAddresses(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, HostAddresses_sequence_of, hf_krb_HostAddresses, ett_krb_HostAddresses);
+
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_msg_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 msgtype;
+
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_msg_type, &msgtype);
+
+ if (do_col_info & check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_str(pinfo->cinfo, COL_INFO,
+ val_to_str(msgtype, krb5_msg_types,
+ "Unknown msg type %#x"));
+ }
+ do_col_info=FALSE;
+
+ /* append the application type to the subtree */
+ proto_item_append_text(tree, " %s", val_to_str(msgtype, krb5_msg_types, "Unknown:0x%x"));
+
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_pvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_pvno, NULL);
+
+ return offset;
+}
+
+
+/*
+ * PrincipalName ::= SEQUENCE {
+ * name-type[0] INTEGER,
+ * name-string[1] SEQUENCE OF GeneralString
+ * }
+ */
+static int
+dissect_krb5_name_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 name_type;
+
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_name_type, &name_type);
+ if(tree){
+ proto_item_append_text(tree, " (%s):",
+ val_to_str(name_type, krb5_princ_types,
+ "Unknown:%d"));
+ }
+ return offset;
+}
+static int
+dissect_krb5_name_string(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ char name_string[256];
+
+ offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_name_string, name_string, 255);
+ if(tree){
+ proto_item_append_text(tree, " %s", name_string);
+ }
+
+ return offset;
+}
+static ber_sequence name_stringe_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_GeneralString, BER_FLAGS_NOOWNTAG, dissect_krb5_name_string },
+};
+static int
+dissect_krb5_name_strings(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, name_stringe_sequence_of, -1, -1);
+
+ return offset;
+}
+static ber_sequence PrincipalName_sequence[] = {
+ { BER_CLASS_CON, 0, 0, dissect_krb5_name_type },
+ { BER_CLASS_CON, 1, 0, dissect_krb5_name_strings },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_sname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_sname, ett_krb_sname);
+
+ return offset;
+}
+static int
+dissect_krb5_cname(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PrincipalName_sequence, hf_krb_cname, ett_krb_cname);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_realm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_realm, NULL, 0);
+ return offset;
+}
+
+static int
+dissect_krb5_crealm(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_crealm, NULL, 0);
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_PA_PAC_REQUEST_flag(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_boolean(pinfo, tree, tvb, offset, hf_krb_PA_PAC_REQUEST_flag);
+ return offset;
+}
+
+
+static ber_sequence PA_PAC_REQUEST_sequence[] = {
+ { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PAC_REQUEST_flag },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PA_PAC_REQUEST(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_PAC_REQUEST_sequence, -1, -1);
+
+ return offset;
+}
+
+
+
+
+static int
+dissect_krb5_SignedData(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb _U_, int offset)
+{
+/*qqq*/
+ return offset;
+}
+
+
+static char ContentType[64]; /*64 chars should be long enough */
+static int
+dissect_krb5_ContentInfo_ContentType(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ ContentType[0]=0;
+ offset=dissect_ber_object_identifier(TRUE, pinfo, tree, tvb, offset, hf_krb_contentinfo_contenttype, ContentType);
+
+ return offset;
+}
+
+/* the content of this structure depends on the ContentType object identifier */
+static int
+dissect_krb5_ContentInfo_content(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ if(!strcmp(ContentType, "1.2.840.113549.1.7.2")){
+ offset=dissect_krb5_SignedData(pinfo, tree, tvb, offset);
+ } else {
+ proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "ContentInfo: dont know how to parse this type yet.");
+ }
+
+ return offset;
+}
+
+static ber_sequence ContentInfo_sequence[] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_OID, BER_FLAGS_NOOWNTAG, dissect_krb5_ContentInfo_ContentType },
+ { BER_CLASS_CON, 0, 0, dissect_krb5_ContentInfo_content },
+ { 0, 0, 0, NULL }
+};
+
+static int
+dissect_krb5_PA_PK_AS_REQ_signedAuthPack(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, ContentInfo_sequence, hf_krb_signedAuthPack, ett_krb_signedAuthPack);
+
+ return offset;
+}
+
+static int
+dissect_krb5_PA_PK_AS_REQ_trustedCertifiers(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ BER_NOT_DECODED_YET("trustedCertifiers");
+
+ return offset;
+}
+static int
+dissect_krb5_PA_PK_AS_REQ_kdcCert(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ BER_NOT_DECODED_YET("kdcCert");
+
+ return offset;
+}
+static int
+dissect_krb5_PA_PK_AS_REQ_encryptionCert(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ BER_NOT_DECODED_YET("encryptionCert");
+
+ return offset;
+}
+
+
+
+static ber_sequence PA_PK_AS_REQ_sequence[] = {
+ { BER_CLASS_CON, 0, 0, dissect_krb5_PA_PK_AS_REQ_signedAuthPack },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_PA_PK_AS_REQ_trustedCertifiers },
+ { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL, dissect_krb5_PA_PK_AS_REQ_kdcCert },
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL, dissect_krb5_PA_PK_AS_REQ_encryptionCert },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PA_PK_AS_REQ(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_PK_AS_REQ_sequence, -1, -1);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_PA_PROV_SRV_LOCATION(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_GeneralString(pinfo, tree, tvb, offset, hf_krb_provsrv_location, NULL, 0);
+
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_kvno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_kvno, NULL);
+
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_seq_number(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_seq_number, NULL);
+
+ return offset;
+}
+
+
+
+#ifdef HAVE_KERBEROS
+static int
+dissect_krb5_pausec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_pausec, NULL);
+ return offset;
+}
+static int
+dissect_krb5_patimestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_patimestamp);
+ return offset;
+}
+static const ber_sequence PA_ENC_TS_ENC_sequence[] = {
+ { BER_CLASS_CON, 0, 0, dissect_krb5_patimestamp },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL, dissect_krb5_pausec },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_decrypt_PA_ENC_TIMESTAMP (packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint8 *plaintext=NULL;
+ int length;
+
+ length=tvb_length_remaining(tvb, offset);
+
+ /* draft-ietf-krb-wg-kerberos-clarifications-05.txt :
+ * 7.5.1
+ * AS-REQ PA_ENC_TIMESTAMP are encrypted with usage
+ * == 1
+ */
+ if(!plaintext){
+ plaintext=decrypt_krb5_data(pinfo, 1, length, tvb_get_ptr(tvb, offset, length), PA_ENC_TIMESTAMP_etype);
+ }
+
+ if(plaintext){
+ tvbuff_t *next_tvb;
+ next_tvb = tvb_new_real_data (plaintext,
+ length,
+ length);
+ tvb_set_child_real_data_tvbuff(tvb, next_tvb);
+
+ /* Add the decrypted data to the data source list. */
+ add_new_data_source(pinfo, next_tvb, "Decrypted Krb5");
+
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, next_tvb, 0, PA_ENC_TS_ENC_sequence, -1, -1);
+
+ }
+ return offset;
+}
+#endif
+
+
+static int
+dissect_krb5_encrypted_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+#ifdef HAVE_KERBEROS
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, dissect_krb5_decrypt_PA_ENC_TIMESTAMP);
+#else
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PA_ENC_TIMESTAMP, NULL);
+#endif
+ return offset;
+}
+static ber_sequence PA_ENC_TIMESTAMP_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_PA_ENC_TIMESTAMP_etype },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
+ dissect_krb5_kvno },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_encrypted_PA_ENC_TIMESTAMP },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PA_ENC_TIMESTAMP(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_ENC_TIMESTAMP_sequence, -1, -1);
+
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_etype_info_salt(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_etype_info_salt, NULL);
+ return offset;
+}
+
+static ber_sequence PA_ENCTYPE_INFO_ENTRY_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_etype },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
+ dissect_krb5_etype_info_salt },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PA_ENCTYPE_INFO_ENTRY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_ENCTYPE_INFO_ENTRY_sequence, -1, -1);
+
+ return offset;
+}
+
+static ber_sequence PA_ENCTYPE_INFO_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_ENCTYPE_INFO_ENTRY },
+};
+static int
+dissect_krb5_PA_ENCTYPE_INFO(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, PA_ENCTYPE_INFO_sequence_of, -1, -1);
+
+ return offset;
+}
+
+/*
+ * PA-DATA ::= SEQUENCE {
+ * padata-type[1] INTEGER,
+ * padata-value[2] OCTET STRING,
+ * -- might be encoded AP-REQ
+ * }
+ */
+guint32 krb_PA_DATA_type;
+static int
+dissect_krb5_PA_DATA_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_PA_DATA_type, &krb_PA_DATA_type);
+ krb_PA_DATA_type&=0xff; /*this is really just one single byte */
+
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(krb_PA_DATA_type, krb5_preauthentication_types,
+ "Unknown:%d"));
+ }
+ return offset;
+}
+static int
+dissect_krb5_PA_DATA_value(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_tree *tree=parent_tree;
+
+ if(ber_last_created_item){
+ tree=proto_item_add_subtree(ber_last_created_item, ett_krb_PA_DATA_tree);
+ }
+
+
+ switch(krb_PA_DATA_type){
+ case KRB5_PA_TGS_REQ:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_application_choice);
+ break;
+ case KRB5_PA_PK_AS_REQ:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PK_AS_REQ);
+ break;
+ case KRB5_PA_PAC_REQUEST:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PAC_REQUEST);
+ break;
+ case KRB5_PA_PROV_SRV_LOCATION:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_PROV_SRV_LOCATION);
+ break;
+ case KRB5_PA_ENC_TIMESTAMP:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENC_TIMESTAMP);
+ break;
+ case KRB5_PA_ENCTYPE_INFO:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, dissect_krb5_PA_ENCTYPE_INFO);
+ break;
+ default:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset,hf_krb_PA_DATA_value, NULL);
+ }
+ return offset;
+/*qqq*/
+}
+
+static ber_sequence PA_DATA_sequence[] = {
+ { BER_CLASS_CON, 1, 0, dissect_krb5_PA_DATA_type },
+ { BER_CLASS_CON, 2, 0, dissect_krb5_PA_DATA_value },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PA_DATA(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PA_DATA_sequence, -1, -1);
+
+ return offset;
+}
+
+
+
+
+/*
+ * padata[3] SEQUENCE OF PA-DATA OPTIONAL,
+ *
+ */
+static ber_sequence PA_DATA_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_PA_DATA },
+};
+static int
+dissect_krb5_padata(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, PA_DATA_sequence_of, hf_krb_padata, ett_krb_padata);
+
+ return offset;
+}
+
+
+
+
+static const true_false_string krb5_ticketflags_forwardable = {
+ "FORWARDABLE tickets are allowed/requested",
+ "Do NOT use forwardable tickets"
+};
+static const true_false_string krb5_ticketflags_forwarded = {
+ "This ticket has been FORWARDED",
+ "This is NOT a forwarded ticket"
+};
+static const true_false_string krb5_ticketflags_proxyable = {
+ "PROXIABLE tickets are allowed/requested",
+ "Do NOT use proxiable tickets"
+};
+static const true_false_string krb5_ticketflags_proxy = {
+ "This is a PROXY ticket",
+ "This ticket has NOT been proxied"
+};
+static const true_false_string krb5_ticketflags_allow_postdate = {
+ "We allow the ticket to be POSTDATED",
+ "We do NOT allow the ticket to be postdated"
+};
+static const true_false_string krb5_ticketflags_postdated = {
+ "This ticket is POSTDATED",
+ "This ticket is NOT postdated"
+};
+static const true_false_string krb5_ticketflags_invalid = {
+ "This ticket is INVALID",
+ "This ticket is NOT invalid"
+};
+static const true_false_string krb5_ticketflags_renewable = {
+ "This ticket is RENEWABLE",
+ "This ticket is NOT renewable"
+};
+static const true_false_string krb5_ticketflags_initial = {
+ "This ticket was granted by AS and not TGT protocol",
+ "This ticket was granted by TGT and not as protocol"
+};
+static const true_false_string krb5_ticketflags_pre_auth = {
+ "The client was PRE-AUTHenticated",
+ "The client was NOT pre-authenticated"
+};
+static const true_false_string krb5_ticketflags_hw_auth = {
+ "The client was authenticated by HardWare",
+ "The client was NOT authenticated using hardware"
+};
+static const true_false_string krb5_ticketflags_transited_policy_checked = {
+ "Kdc has performed TRANSITED POLICY CHECKING",
+ "Kdc has NOT performed transited policy checking"
+};
+static const true_false_string krb5_ticketflags_ok_as_delegate = {
+ "This ticket is OK AS a DELEGATED ticket",
+ "This ticket is NOT ok as a delegated ticket"
+};
+
+static int* TicketFlags_bits[] = {
+ &hf_krb_TicketFlags_forwardable,
+ &hf_krb_TicketFlags_forwarded,
+ &hf_krb_TicketFlags_proxyable,
+ &hf_krb_TicketFlags_proxy,
+ &hf_krb_TicketFlags_allow_postdate,
+ &hf_krb_TicketFlags_postdated,
+ &hf_krb_TicketFlags_invalid,
+ &hf_krb_TicketFlags_renewable,
+ &hf_krb_TicketFlags_initial,
+ &hf_krb_TicketFlags_pre_auth,
+ &hf_krb_TicketFlags_hw_auth,
+ &hf_krb_TicketFlags_transited_policy_checked,
+ &hf_krb_TicketFlags_ok_as_delegate,
+ NULL
+};
+
+static int
+dissect_krb5_TicketFlags(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_bitstring32(FALSE, pinfo, tree, tvb, offset, TicketFlags_bits, hf_krb_TicketFlags, ett_krb_Ticket_Flags, NULL);
+ return offset;
+}
+
+
+static guint32 keytype;
+static int
+dissect_krb5_keytype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_keytype, &keytype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(keytype, krb5_encryption_types,
+ "%#x"));
+ }
+ return offset;
+}
+static int keylength;
+static const char *keyvalue;
+static int
+store_keyvalue(packet_info *pinfo _U_, proto_tree *tree _U_, tvbuff_t *tvb, int offset)
+{
+ keylength=tvb_length_remaining(tvb, offset);
+ keyvalue=tvb_get_ptr(tvb, offset, keylength);
+ return 0;
+}
+static int
+dissect_krb5_keyvalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_keyvalue, store_keyvalue);
+ return offset;
+}
+
+
+/*
+ * EncryptionKey ::= SEQUENCE {
+ * keytype [0] int32
+ * keyvalue [1] octet string
+ */
+static ber_sequence EncryptionKey_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_keytype },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_keyvalue },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_key(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncryptionKey_sequence, hf_krb_key, ett_krb_key);
+
+#ifdef HAVE_KERBEROS
+ add_encryption_key(pinfo, keytype, keylength, keyvalue);
+#endif
+ return offset;
+}
+static int
+dissect_krb5_subkey(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncryptionKey_sequence, hf_krb_subkey, ett_krb_subkey);
+#ifdef HAVE_KERBEROS
+ add_encryption_key(pinfo, keytype, keylength, keyvalue);
+#endif
+ return offset;
+}
+
+
+
+static int
+dissect_krb5_PAC_LOGON_INFO(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_item *item=NULL;
+ proto_tree *tree=NULL;
+ guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ dcerpc_info di; /* fake dcerpc_info struct */
+ void *old_private_data;
+
+ item=proto_tree_add_item(parent_tree, hf_krb_PAC_LOGON_INFO, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+ if(parent_tree){
+ tree=proto_item_add_subtree(item, ett_krb_PAC_LOGON_INFO);
+ }
+
+ /* skip the first 20 bytes, they look like a unique ndr pointer
+ followed by (where did it come from?) a contect_handle ?*/
+ proto_tree_add_text(tree, tvb, offset, 20, "unknown: is this an undocumented policy handle?");
+ offset+=20;
+
+
+ /* the PAC_LOGON_INFO blob */
+ /* fake whatever state the dcerpc runtime support needs */
+ di.conformant_run=0;
+ di.call_data=NULL;
+ old_private_data=pinfo->private_data;
+ pinfo->private_data=&di;
+ init_ndr_pointer_list(pinfo);
+ offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, drep,
+ netlogon_dissect_PAC_LOGON_INFO, NDR_POINTER_REF,
+ "PAC_LOGON_INFO:", -1);
+ pinfo->private_data=old_private_data;
+
+ return offset;
+}
+
+static int
+dissect_krb5_PAC_CREDENTIAL_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_item *item=NULL;
+ proto_tree *tree=NULL;
+
+ item=proto_tree_add_item(parent_tree, hf_krb_PAC_CREDENTIAL_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+ if(parent_tree){
+ tree=proto_item_add_subtree(item, ett_krb_PAC_CREDENTIAL_TYPE);
+ }
+
+/*qqq*/
+ return offset;
+}
+
+static int
+dissect_krb5_PAC_SERVER_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_item *item=NULL;
+ proto_tree *tree=NULL;
+
+ item=proto_tree_add_item(parent_tree, hf_krb_PAC_SERVER_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+ if(parent_tree){
+ tree=proto_item_add_subtree(item, ett_krb_PAC_SERVER_CHECKSUM);
+ }
+
+ /* signature type */
+ proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
+ offset+=4;
+
+ /* signature data */
+ proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+
+ return offset;
+}
+
+static int
+dissect_krb5_PAC_PRIVSVR_CHECKSUM(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_item *item=NULL;
+ proto_tree *tree=NULL;
+
+ item=proto_tree_add_item(parent_tree, hf_krb_PAC_PRIVSVR_CHECKSUM, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+ if(parent_tree){
+ tree=proto_item_add_subtree(item, ett_krb_PAC_PRIVSVR_CHECKSUM);
+ }
+
+ /* signature type */
+ proto_tree_add_item(tree, hf_krb_pac_signature_type, tvb, offset, 4, TRUE);
+ offset+=4;
+
+ /* signature data */
+ proto_tree_add_item(tree, hf_krb_pac_signature_signature, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+
+ return offset;
+}
+
+static int
+dissect_krb5_PAC_CLIENT_INFO_TYPE(packet_info *pinfo _U_, proto_tree *parent_tree, tvbuff_t *tvb, int offset)
+{
+ proto_item *item=NULL;
+ proto_tree *tree=NULL;
+ guint16 namelen;
+ char *name;
+
+ item=proto_tree_add_item(parent_tree, hf_krb_PAC_CLIENT_INFO_TYPE, tvb, offset, tvb_length_remaining(tvb, offset), FALSE);
+ if(parent_tree){
+ tree=proto_item_add_subtree(item, ett_krb_PAC_CLIENT_INFO_TYPE);
+ }
+
+ /* clientid */
+ offset = dissect_smb_64bit_time(tvb, tree, offset,
+ hf_krb_pac_clientid);
+
+ /* name length */
+ namelen=tvb_get_letohs(tvb, offset);
+ proto_tree_add_uint(tree, hf_krb_pac_namelen, tvb, offset, 2, namelen);
+ offset+=2;
+
+ /* client name */
+ name=tvb_fake_unicode(tvb, offset, namelen/2, TRUE);
+ proto_tree_add_string(tree, hf_krb_pac_clientname, tvb, offset, namelen, name);
+ offset+=namelen;
+
+ return offset;
+}
+
+static int
+dissect_krb5_AD_WIN2K_PAC_struct(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 pac_type;
+ guint32 pac_size;
+ guint32 pac_offset;
+ proto_item *it=NULL;
+ proto_tree *tr=NULL;
+ tvbuff_t *next_tvb;
+
+ /* type of pac data */
+ pac_type=tvb_get_letohl(tvb, offset);
+ it=proto_tree_add_uint(tree, hf_krb_w2k_pac_type, tvb, offset, 4, pac_type);
+ if(it){
+ tr=proto_item_add_subtree(it, ett_krb_PAC);
+ }
+
+ offset += 4;
+
+ /* size of pac data */
+ pac_size=tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tr, hf_krb_w2k_pac_size, tvb, offset, 4, pac_size);
+ offset += 4;
+
+ /* offset to pac data */
+ pac_offset=tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tr, hf_krb_w2k_pac_offset, tvb, offset, 4, pac_offset);
+ offset += 8;
+
+
+ next_tvb=tvb_new_subset(tvb, pac_offset, pac_size, pac_size);
+ switch(pac_type){
+ case PAC_LOGON_INFO:
+ dissect_krb5_PAC_LOGON_INFO(pinfo, tr, next_tvb, 0);
+ break;
+ case PAC_CREDENTIAL_TYPE:
+ dissect_krb5_PAC_CREDENTIAL_TYPE(pinfo, tr, next_tvb, 0);
+ break;
+ case PAC_SERVER_CHECKSUM:
+ dissect_krb5_PAC_SERVER_CHECKSUM(pinfo, tr, next_tvb, 0);
+ break;
+ case PAC_PRIVSVR_CHECKSUM:
+ dissect_krb5_PAC_PRIVSVR_CHECKSUM(pinfo, tr, next_tvb, 0);
+ break;
+ case PAC_CLIENT_INFO_TYPE:
+ dissect_krb5_PAC_CLIENT_INFO_TYPE(pinfo, tr, next_tvb, 0);
+ break;
+ default:;
+/*qqq*/
+ }
+ return offset;
+}
+
+static int
+dissect_krb5_AD_WIN2K_PAC(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 entries;
+ guint32 version;
+ guint32 i;
+
+ /* first in the PAC structure comes the number of entries */
+ entries=tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_krb_w2k_pac_entries, tvb, offset, 4, entries);
+ offset += 4;
+
+ /* second comes the version */
+ version=tvb_get_letohl(tvb, offset);
+ proto_tree_add_uint(tree, hf_krb_w2k_pac_version, tvb, offset, 4, version);
+ offset += 4;
+
+ for(i=0;i<entries;i++){
+ offset=dissect_krb5_AD_WIN2K_PAC_struct(pinfo, tree, tvb, offset);
+ }
+
+ return offset;
+}
+
+static guint32 IF_RELEVANT_type;
+static int
+dissect_krb5_IF_RELEVANT_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_IF_RELEVANT_type, &IF_RELEVANT_type);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(IF_RELEVANT_type, krb5_ad_types,
+ "%#x"));
+ }
+ return offset;
+}
+static int
+dissect_krb5_IF_RELEVANT_value(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ switch(IF_RELEVANT_type){
+ case KRB5_AD_WIN2K_PAC:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, dissect_krb5_AD_WIN2K_PAC);
+ break;
+ default:
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_IF_RELEVANT_value, NULL);
+ }
+ return offset;
+}
+static ber_sequence IF_RELEVANT_item_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_IF_RELEVANT_type },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_IF_RELEVANT_value },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_IF_RELEVANT_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_item_sequence, hf_krb_IF_RELEVANT, ett_krb_IF_RELEVANT);
+
+ return offset;
+}
+
+static ber_sequence IF_RELEVANT_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_IF_RELEVANT_item },
+};
+
+static int
+dissect_krb5_IF_RELEVANT(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, IF_RELEVANT_sequence_of, -1, -1);
+
+ return offset;
+}
+
+static guint32 adtype;
+static int
+dissect_krb5_adtype(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_adtype, &adtype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(adtype, krb5_ad_types,
+ "%#x"));
+ }
+ return offset;
+}
+static int
+dissect_krb5_advalue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ switch(adtype){
+ case KRB5_AD_IF_RELEVANT:
+ offset=dissect_ber_octet_string_wcb(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, dissect_krb5_IF_RELEVANT);
+ break;
+ default:
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_advalue, NULL);
+ }
+ return offset;
+}
+/*
+ * AuthorizationData ::= SEQUENCE {
+ * ad-type [0] int32
+ * ad-data [1] octet string
+ */
+static ber_sequence AuthorizationData_item_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_adtype },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_advalue },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_AuthorizationData_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, AuthorizationData_item_sequence, hf_krb_AuthorizationData, ett_krb_AuthorizationData);
+
+ return offset;
+}
+
+static ber_sequence AuthorizationData_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_AuthorizationData_item },
+};
+static int
+dissect_krb5_AuthorizationData(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, AuthorizationData_sequence_of, -1, -1);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_transited_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ guint32 trtype;
+
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_transitedtype, &trtype);
+ if(tree){
+ proto_item_append_text(tree, " %s",
+ val_to_str(trtype, krb5_transited_types,
+ "%#x"));
+ }
+ return offset;
+}
+
+static int
+dissect_krb5_transited_contents(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_transitedcontents, NULL);
+ return offset;
+}
+
+/*
+ * TransitedEncoding ::= SEQUENCE {
+ * tr-type [0] int32
+ * contents [1] octet string
+ */
+static ber_sequence TransitedEncoding_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_transited_type },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_transited_contents },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_transited(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, TransitedEncoding_sequence, hf_krb_TransitedEncoding, ett_krb_TransitedEncoding);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_authtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_authtime);
+ return offset;
+}
+static int
+dissect_krb5_starttime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_starttime);
+ return offset;
+}
+static int
+dissect_krb5_endtime(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_endtime);
+ return offset;
+}
+static int
+dissect_krb5_renew_till(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_renew_till);
+ return offset;
+}
+
+/*
+ * EncTicketPart ::= SEQUENCE {
+ * flags [0] TicketFlags,
+ * key [1] EncryptionKey,
+ * crealm [2] Realm,
+ * cname [3] PrincipalName,
+ * transited [4] TransitedEncoding,
+ * authtime [5] KerberosTime,
+ * starttime [6] KerberosTime OPTIONAL,
+ * endtime [7] KerberosTime,
+ * renew-till [8] KerberosTime OPTIONAL,
+ * caddr [9] HostAddresses OPTIONAL,
+ * authorization-data [10] AuthorizationData OPTIONAL
+ * }
+ */
+static ber_sequence EncTicketPart_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_TicketFlags },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_key },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_crealm },
+ { BER_CLASS_CON, 3, 0,
+ dissect_krb5_cname },
+ { BER_CLASS_CON, 4, 0,
+ dissect_krb5_transited },
+ { BER_CLASS_CON, 5, 0,
+ dissect_krb5_authtime },
+ { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
+ dissect_krb5_starttime },
+ { BER_CLASS_CON, 7, 0,
+ dissect_krb5_endtime },
+ { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
+ dissect_krb5_renew_till },
+ { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
+ dissect_krb5_HostAddresses },
+ { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL,
+ dissect_krb5_AuthorizationData },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_EncTicketPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncTicketPart_sequence, hf_krb_EncTicketPart, ett_krb_EncTicketPart);
+
+ return offset;
+}
+
+
+
+
+
+
+/*
+ * EncAPRepPart ::= SEQUENCE {
+ * ctime [0] KerberosTime
+ * cusec [1] Microseconds
+ * subkey [2] encryptionKey OPTIONAL
+ * seq-number [3] uint32 OPTIONAL
+ * }
+ */
+static ber_sequence EncAPRepPart_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_ctime },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_cusec },
+ { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
+ dissect_krb5_subkey },
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
+ dissect_krb5_seq_number },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_EncAPRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncAPRepPart_sequence, hf_krb_EncAPRepPart, ett_krb_EncAPRepPart);
+
+ return offset;
+}
+
+
+
+static guint32 lr_type;
+static const value_string krb5_lr_types[] = {
+ { 0 , "No information available" },
+ { 1 , "Time of last initial TGT request" },
+ { 2 , "Time of last initial request" },
+ { 3 , "Time of issue of latest TGT ticket" },
+ { 4 , "Time of last renewal" },
+ { 5 , "Time of last request" },
+ { 6 , "Time when password will expire" },
+ { 7 , "Time when account will expire" },
+ { 0, NULL }
+};
+static int
+dissect_krb5_lr_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_lr_type, &lr_type);
+
+ return offset;
+}
+static int
+dissect_krb5_lr_value(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_lr_time);
+
+ return offset;
+}
+
+static ber_sequence LastReq_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_lr_type },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_lr_value },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_LastReq(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, LastReq_sequence, hf_krb_LastReq, ett_krb_LastReq);
+
+ return offset;
+}
+static ber_sequence LastReq_sequence_of[1] = {
+ { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_krb5_LastReq },
+};
+static int
+dissect_krb5_LastReq_sequence_of(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence_of(FALSE, pinfo, tree, tvb, offset, LastReq_sequence_of, hf_krb_LastReqs, ett_krb_LastReqs);
+
+ return offset;
+}
+
+static int
+dissect_krb5_key_expiration(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_key_expire);
+ return offset;
+}
+
+static ber_sequence EncKDCRepPart_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_key },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_LastReq_sequence_of },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_nonce },
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
+ dissect_krb5_key_expiration },
+ { BER_CLASS_CON, 4, 0,
+ dissect_krb5_TicketFlags },
+ { BER_CLASS_CON, 5, 0,
+ dissect_krb5_authtime },
+ { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
+ dissect_krb5_starttime },
+ { BER_CLASS_CON, 7, 0,
+ dissect_krb5_endtime },
+ { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
+ dissect_krb5_renew_till },
+ { BER_CLASS_CON, 9, 0,
+ dissect_krb5_realm },
+ { BER_CLASS_CON, 10, 0,
+ dissect_krb5_sname },
+ { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL,
+ dissect_krb5_HostAddresses },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_EncKDCRepPart(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, EncKDCRepPart_sequence, hf_krb_EncKDCRepPart, ett_krb_EncKDCRepPart);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_authenticator_vno(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_authenticator_vno, NULL);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_checksum_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_checksum_type, NULL);
+
+ return offset;
+}
+static int
+dissect_krb5_checksum_checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_checksum_checksum, NULL);
+ return offset;
+}
+
+/*
+ * Checksum ::= SEQUENCE {
+ * }
+ */
+static ber_sequence Checksum_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_checksum_type },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_checksum_checksum },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_Checksum(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Checksum_sequence, hf_krb_Checksum, ett_krb_Checksum);
+
+ return offset;
+}
+
+/*
+ * Authenticator ::= SEQUENCE {
+ * authenticator-vno [0] integer
+ * crealm [1] Realm
+ * cname [2] PrincipalName
+ * cksum [3] Checksum OPTIONAL
+ * cusec [4] Microseconds
+ * ctime [5] KerberosTime
+ * subkey [6] encryptionKey OPTIONAL
+ * seq-number [7] uint32 OPTIONAL
+ * authorization-data [8] AuthorizationData OPTIONAL
+ * }
+ */
+static ber_sequence Authenticator_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_authenticator_vno },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_crealm },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_cname },
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
+ dissect_krb5_Checksum },
+ { BER_CLASS_CON, 4, 0,
+ dissect_krb5_cusec },
+ { BER_CLASS_CON, 5, 0,
+ dissect_krb5_ctime },
+ { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
+ dissect_krb5_subkey },
+ { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL,
+ dissect_krb5_seq_number },
+ { BER_CLASS_CON, 8, BER_FLAGS_OPTIONAL,
+ dissect_krb5_AuthorizationData },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_Authenticator(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, Authenticator_sequence, hf_krb_Authenticator, ett_krb_Authenticator);
+
+ return offset;
+}
+
+
+/*
+ * PRIV-BODY ::= SEQUENCE {
+ * KRB-PRIV ::= [APPLICATION 21] SEQUENCE {
+ * pvno[0] INTEGER,
+ * msg-type[1] INTEGER,
+ * enc-part[3] EncryptedData
+ * }
+ */
+static int
+dissect_krb5_encrypted_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_encrypted_PRIV, NULL);
+ return offset;
+}
+static ber_sequence ENC_PRIV_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_etype },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
+ dissect_krb5_kvno },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_encrypted_PRIV },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_ENC_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, ENC_PRIV_sequence, hf_krb_ENC_PRIV, ett_krb_PRIV_enc);
+ return offset;
+}
+static ber_sequence PRIV_BODY_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_pvno },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_msg_type },
+ { BER_CLASS_CON, 3, 0,
+ dissect_krb5_ENC_PRIV },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_PRIV(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, PRIV_BODY_sequence, hf_krb_PRIV_BODY, ett_krb_PRIV);
+
+ return offset;
+}
+
+
+static int
+dissect_krb5_SAFE_BODY_user_data(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ tvbuff_t *new_tvb;
+ offset=dissect_ber_octet_string(FALSE, pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_user_data, &new_tvb);
+ call_kerberos_callbacks(pinfo, tree, new_tvb, KRB_CBTAG_SAFE_USER_DATA);
+ return offset;
+}
+static int
+dissect_krb5_SAFE_BODY_timestamp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_generalized_time(pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_timestamp);
+ return offset;
+}
+
+static int
+dissect_krb5_SAFE_BODY_usec(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+ offset=dissect_ber_integer(pinfo, tree, tvb, offset, hf_krb_SAFE_BODY_usec, NULL);
+ return offset;
+}
+
+static ber_sequence SAFE_BODY_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_SAFE_BODY_user_data },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
+ dissect_krb5_SAFE_BODY_timestamp },
+ { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL,
+ dissect_krb5_SAFE_BODY_usec },
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
+ dissect_krb5_seq_number },
+ /*XXX this one is OPTIONAL in packetcable? but mandatory in kerberos */
+ { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
+ dissect_krb5_s_address },
+ { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
+ dissect_krb5_HostAddresses },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_SAFE_BODY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, SAFE_BODY_sequence, -1, -1);
+
+ return offset;
+}
+
+
+
+static ber_sequence SAFE_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_pvno },
+ { BER_CLASS_CON, 1, 0,
+ dissect_krb5_msg_type },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_SAFE_BODY },
+ { BER_CLASS_CON, 3, 0,
+ dissect_krb5_Checksum },
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_SAFE(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, SAFE_sequence, -1, -1);
+
+ return offset;
+}
+
+
+/*
+ * KDC-REQ-BODY ::= SEQUENCE {
+ * kdc-options[0] KDCOptions,
+ * cname[1] PrincipalName OPTIONAL,
+ * -- Used only in AS-REQ
+ * realm[2] Realm, -- Server's realm
+ * -- Also client's in AS-REQ
+ * sname[3] PrincipalName OPTIONAL,
+ * from[4] KerberosTime OPTIONAL,
+ * till[5] KerberosTime,
+ * rtime[6] KerberosTime OPTIONAL,
+ * nonce[7] INTEGER,
+ * etype[8] SEQUENCE OF INTEGER, -- EncryptionType,
+ * -- in preference order
+ * addresses[9] HostAddresses OPTIONAL,
+ * enc-authorization-data[10] EncryptedData OPTIONAL,
+ * -- Encrypted AuthorizationData encoding
+ * additional-tickets[11] SEQUENCE OF Ticket OPTIONAL
+ * }
+ *
+ */
+static ber_sequence KDC_REQ_BODY_sequence[] = {
+ { BER_CLASS_CON, 0, 0,
+ dissect_krb5_KDCOptions },
+ { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL,
+ dissect_krb5_cname },
+ { BER_CLASS_CON, 2, 0,
+ dissect_krb5_realm},
+ { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL,
+ dissect_krb5_sname },
+ { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL,
+ dissect_krb5_from },
+ /* this field is not optional in the kerberos spec,
+ * however, in the packetcable spec it is optional.
+ * make it optional here since normal kerberos will
+ * still decode the pdu correctly.
+ */
+ { BER_CLASS_CON, 5, BER_FLAGS_OPTIONAL,
+ dissect_krb5_till },
+ { BER_CLASS_CON, 6, BER_FLAGS_OPTIONAL,
+ dissect_krb5_rtime },
+ { BER_CLASS_CON, 7, 0,
+ dissect_krb5_nonce },
+ { BER_CLASS_CON, 8, 0,
+ dissect_krb5_etype_sequence_of },
+ { BER_CLASS_CON, 9, BER_FLAGS_OPTIONAL,
+ dissect_krb5_HostAddresses },
+/* XXX [10] and [11] enc-authorization-data and additional-tickets should be added */
+ { 0, 0, 0, NULL }
+};
+static int
+dissect_krb5_KDC_REQ_BODY(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset)
+{
+
+ offset=dissect_ber_sequence(FALSE, pinfo, tree, tvb, offset, KDC_REQ_BODY_sequence, hf_krb_KDC_REQ_BODY, ett_krb_request);