GSSAPI: Avoid dissecting checksum in signed-only KRB_TOKEN_CFX_WRAP
In KRB_TOKEN_CFX_WRAP (RFC 4121), for signed-only Wrap tokens ("Wrap tokens without confidentiality"), the plaintext is followed by the checksum, unlike in other implementations where the all the GSSAPI bits, including the checksum, precede the plaintext. For those cases, the calling dissector cannot simply dissect the entire original tvb after the returned offset, as it's not all plaintext. Instead, place the plaintext without checksum subset in gssapi_decrypted_tvb and return it to the caller. In these cases, gssapi_data_encrypted will be set to FALSE, to allow dissectors that wish to distinguished signed-and-sealed from signed-only. For dissectors that do not care to distinguish the cases, this requires no change. Update the documentation in the GSSAPI header to describe this. Fix #9398.
This commit is contained in:
parent
09f6a3aaa6
commit
3540bbc969
|
@ -1247,41 +1247,46 @@ static void
|
||||||
if(ver_len==0){
|
if(ver_len==0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
if (gssapi_encrypt.gssapi_data_encrypted) {
|
||||||
tvbuff_t *decr_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
||||||
proto_tree *enc_tree = NULL;
|
tvbuff_t *decr_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
||||||
|
proto_tree *enc_tree = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The LDAP payload (blob) was encrypted and we were able to decrypt it.
|
* The LDAP payload (blob) was encrypted and we were able to decrypt it.
|
||||||
* The data was signed via a MIC token, sealed (encrypted), and "wrapped"
|
* The data was signed via a MIC token, sealed (encrypted), and "wrapped"
|
||||||
* within the mechanism's "blob." Call dissect_ldap_payload to dissect
|
* within the mechanism's "blob." Call dissect_ldap_payload to dissect
|
||||||
* one or more LDAPMessages such as searchRequest messages within this
|
* one or more LDAPMessages such as searchRequest messages within this
|
||||||
* payload.
|
* payload.
|
||||||
*/
|
*/
|
||||||
col_set_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
|
col_set_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
|
||||||
|
|
||||||
if (sasl_tree) {
|
if (sasl_tree) {
|
||||||
guint decr_len = tvb_reported_length(decr_tvb);
|
guint decr_len = tvb_reported_length(decr_tvb);
|
||||||
|
|
||||||
enc_tree = proto_tree_add_subtree_format(sasl_tree, decr_tvb, 0, -1,
|
enc_tree = proto_tree_add_subtree_format(sasl_tree, decr_tvb, 0, -1,
|
||||||
ett_ldap_payload, NULL, "GSS-API Encrypted payload (%d byte%s)",
|
ett_ldap_payload, NULL, "GSS-API Encrypted payload (%d byte%s)",
|
||||||
decr_len, plurality(decr_len, "", "s"));
|
decr_len, plurality(decr_len, "", "s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The LDAP message was encrypted but couldn't be decrypted so just display the
|
||||||
|
* encrypted data all of which is found in Packet Bytes.
|
||||||
|
*/
|
||||||
|
col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
|
||||||
|
sasl_len-ver_len, plurality(sasl_len-ver_len, "", "s"));
|
||||||
|
|
||||||
|
proto_tree_add_item(sasl_tree, hf_ldap_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tvbuff_t *plain_tvb;
|
||||||
|
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
||||||
|
plain_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
||||||
|
} else {
|
||||||
|
plain_tvb = tvb_new_subset_remaining(gssapi_tvb, ver_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
|
|
||||||
}
|
|
||||||
else if (gssapi_encrypt.gssapi_data_encrypted) {
|
|
||||||
/*
|
|
||||||
* The LDAP message was encrypted but couldn't be decrypted so just display the
|
|
||||||
* encrypted data all of which is found in Packet Bytes.
|
|
||||||
*/
|
|
||||||
col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
|
|
||||||
sasl_len-ver_len, plurality(sasl_len-ver_len, "", "s"));
|
|
||||||
|
|
||||||
proto_tree_add_item(sasl_tree, hf_ldap_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tvbuff_t *plain_tvb = tvb_new_subset_remaining(gssapi_tvb, ver_len);
|
|
||||||
proto_tree *plain_tree = NULL;
|
proto_tree *plain_tree = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1029,6 +1029,8 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
returned_offset = offset;
|
returned_offset = offset;
|
||||||
gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset,
|
gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset,
|
||||||
inner_token_len);
|
inner_token_len);
|
||||||
|
gssapi_encrypt->gssapi_decrypted_tvb = tvb_new_subset_length(tvb, offset,
|
||||||
|
inner_token_len);
|
||||||
|
|
||||||
offset += inner_token_len;
|
offset += inner_token_len;
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,20 @@ typedef struct _gssapi_oid_value {
|
||||||
|
|
||||||
/**< Extra data for handling of decryption of GSSAPI wrapped tvbuffs.
|
/**< Extra data for handling of decryption of GSSAPI wrapped tvbuffs.
|
||||||
Caller sets decrypt_gssapi_tvb if this service is requested.
|
Caller sets decrypt_gssapi_tvb if this service is requested.
|
||||||
If gssapi_encrypted_tvb is NULL, then the rest of the tvb data following
|
If, on a successful return, gssapi_data_encrypted is FALSE, the wrapped
|
||||||
the gssapi blob itself is decrypted othervise the gssapi_encrypted_tvb
|
tvbuff was signed (i.e., an encrypted signature was present, to check
|
||||||
tvb will be decrypted (DCERPC has the data before the gssapi blob)
|
|
||||||
If, on return, gssapi_data_encrypted is FALSE, the wrapped tvbuff
|
|
||||||
was signed (i.e., an encrypted signature was present, to check
|
|
||||||
whether the data was modified by a man in the middle) but not sealed
|
whether the data was modified by a man in the middle) but not sealed
|
||||||
(i.e., the data itself wasn't encrypted).
|
(i.e., the data itself wasn't encrypted).
|
||||||
|
If gssapi_encrypted_tvb is NULL, then the rest of the tvb data following
|
||||||
|
the gssapi blob itself is decrypted otherwise the gssapi_encrypted_tvb
|
||||||
|
tvb will be decrypted (DCERPC has the data before the gssapi blob).
|
||||||
|
In the latter case, gssapi_decrypted_tvb contains the decrypted data if
|
||||||
|
decryption is successful and is NULL if not.
|
||||||
|
If gssapi_data_encrypted is FALSE and gssapi_decrypted_tvb is not NULL,
|
||||||
|
then it contains the plaintext data, for cases when the plaintext data
|
||||||
|
was followed by the checksum, e.g. KRB_TOKEN_CFX_WRAP (RFC 4121),
|
||||||
|
as the calling dissector cannot simply dissect all the data after
|
||||||
|
the returned offset.
|
||||||
*/
|
*/
|
||||||
typedef struct _gssapi_encrypt_info
|
typedef struct _gssapi_encrypt_info
|
||||||
{
|
{
|
||||||
|
|
|
@ -4053,41 +4053,46 @@ static void
|
||||||
if(ver_len==0){
|
if(ver_len==0){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
if (gssapi_encrypt.gssapi_data_encrypted) {
|
||||||
tvbuff_t *decr_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
||||||
proto_tree *enc_tree = NULL;
|
tvbuff_t *decr_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
||||||
|
proto_tree *enc_tree = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The LDAP payload (blob) was encrypted and we were able to decrypt it.
|
* The LDAP payload (blob) was encrypted and we were able to decrypt it.
|
||||||
* The data was signed via a MIC token, sealed (encrypted), and "wrapped"
|
* The data was signed via a MIC token, sealed (encrypted), and "wrapped"
|
||||||
* within the mechanism's "blob." Call dissect_ldap_payload to dissect
|
* within the mechanism's "blob." Call dissect_ldap_payload to dissect
|
||||||
* one or more LDAPMessages such as searchRequest messages within this
|
* one or more LDAPMessages such as searchRequest messages within this
|
||||||
* payload.
|
* payload.
|
||||||
*/
|
*/
|
||||||
col_set_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
|
col_set_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
|
||||||
|
|
||||||
if (sasl_tree) {
|
if (sasl_tree) {
|
||||||
guint decr_len = tvb_reported_length(decr_tvb);
|
guint decr_len = tvb_reported_length(decr_tvb);
|
||||||
|
|
||||||
enc_tree = proto_tree_add_subtree_format(sasl_tree, decr_tvb, 0, -1,
|
enc_tree = proto_tree_add_subtree_format(sasl_tree, decr_tvb, 0, -1,
|
||||||
ett_ldap_payload, NULL, "GSS-API Encrypted payload (%d byte%s)",
|
ett_ldap_payload, NULL, "GSS-API Encrypted payload (%d byte%s)",
|
||||||
decr_len, plurality(decr_len, "", "s"));
|
decr_len, plurality(decr_len, "", "s"));
|
||||||
|
}
|
||||||
|
|
||||||
|
dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The LDAP message was encrypted but couldn't be decrypted so just display the
|
||||||
|
* encrypted data all of which is found in Packet Bytes.
|
||||||
|
*/
|
||||||
|
col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
|
||||||
|
sasl_len-ver_len, plurality(sasl_len-ver_len, "", "s"));
|
||||||
|
|
||||||
|
proto_tree_add_item(sasl_tree, hf_ldap_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tvbuff_t *plain_tvb;
|
||||||
|
if (gssapi_encrypt.gssapi_decrypted_tvb) {
|
||||||
|
plain_tvb = gssapi_encrypt.gssapi_decrypted_tvb;
|
||||||
|
} else {
|
||||||
|
plain_tvb = tvb_new_subset_remaining(gssapi_tvb, ver_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
|
|
||||||
}
|
|
||||||
else if (gssapi_encrypt.gssapi_data_encrypted) {
|
|
||||||
/*
|
|
||||||
* The LDAP message was encrypted but couldn't be decrypted so just display the
|
|
||||||
* encrypted data all of which is found in Packet Bytes.
|
|
||||||
*/
|
|
||||||
col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
|
|
||||||
sasl_len-ver_len, plurality(sasl_len-ver_len, "", "s"));
|
|
||||||
|
|
||||||
proto_tree_add_item(sasl_tree, hf_ldap_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tvbuff_t *plain_tvb = tvb_new_subset_remaining(gssapi_tvb, ver_len);
|
|
||||||
proto_tree *plain_tree = NULL;
|
proto_tree *plain_tree = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -872,18 +872,26 @@ dissect_pgsql_gssapi_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
|
||||||
/* GSS-API couldn't do anything with it. */
|
/* GSS-API couldn't do anything with it. */
|
||||||
return tvb_captured_length(tvb);
|
return tvb_captured_length(tvb);
|
||||||
}
|
}
|
||||||
if (encrypt.gssapi_decrypted_tvb) {
|
if (encrypt.gssapi_data_encrypted) {
|
||||||
tvbuff_t *decr_tvb = encrypt.gssapi_decrypted_tvb;
|
if (encrypt.gssapi_decrypted_tvb) {
|
||||||
add_new_data_source(pinfo, encrypt.gssapi_decrypted_tvb, "Decrypted GSS-API");
|
tvbuff_t *decr_tvb = encrypt.gssapi_decrypted_tvb;
|
||||||
dissect_pgsql_msg(decr_tvb, pinfo, ptree, data);
|
add_new_data_source(pinfo, encrypt.gssapi_decrypted_tvb, "Decrypted GSS-API");
|
||||||
} else if (encrypt.gssapi_data_encrypted) {
|
dissect_pgsql_msg(decr_tvb, pinfo, ptree, data);
|
||||||
/* Encrypted but couldn't be decrypted. */
|
} else {
|
||||||
proto_tree_add_item(ptree, hf_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
/* Encrypted but couldn't be decrypted. */
|
||||||
|
proto_tree_add_item(ptree, hf_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* No encrypted (sealed) payload. If any bytes are left, that is
|
/* No encrypted (sealed) payload. If any bytes are left, that is
|
||||||
* signed-only payload. */
|
* signed-only payload. */
|
||||||
if (tvb_reported_length_remaining(gssapi_tvb, ver_len)) {
|
tvbuff_t *plain_tvb;
|
||||||
dissect_pgsql_msg(tvb_new_subset_remaining(gssapi_tvb, ver_len), pinfo, ptree, data);
|
if (encrypt.gssapi_decrypted_tvb) {
|
||||||
|
plain_tvb = encrypt.gssapi_decrypted_tvb;
|
||||||
|
} else {
|
||||||
|
plain_tvb = tvb_new_subset_remaining(gssapi_tvb, ver_len);
|
||||||
|
}
|
||||||
|
if (tvb_reported_length(plain_tvb)) {
|
||||||
|
dissect_pgsql_msg(plain_tvb, pinfo, ptree, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tvb_captured_length(tvb);
|
return tvb_captured_length(tvb);
|
||||||
|
|
|
@ -1479,6 +1479,8 @@ dissect_spnego_krb5_cfx_wrap_base(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||||
returned_offset = offset;
|
returned_offset = offset;
|
||||||
gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset,
|
gssapi_encrypt->gssapi_wrap_tvb = tvb_new_subset_length(tvb, offset,
|
||||||
inner_token_len);
|
inner_token_len);
|
||||||
|
gssapi_encrypt->gssapi_decrypted_tvb = tvb_new_subset_length(tvb, offset,
|
||||||
|
inner_token_len);
|
||||||
|
|
||||||
offset += inner_token_len;
|
offset += inner_token_len;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue