summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-pgsql.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--epan/dissectors/packet-pgsql.c247
1 files changed, 133 insertions, 114 deletions
diff --git a/epan/dissectors/packet-pgsql.c b/epan/dissectors/packet-pgsql.c
index 1bb5b757..b3d99535 100644
--- a/epan/dissectors/packet-pgsql.c
+++ b/epan/dissectors/packet-pgsql.c
@@ -27,80 +27,80 @@ static dissector_handle_t tls_handle;
static dissector_handle_t gssapi_handle;
static dissector_handle_t ntlmssp_handle;
-static int proto_pgsql = -1;
-static int hf_frontend = -1;
-static int hf_type = -1;
-static int hf_length = -1;
-static int hf_version_major = -1;
-static int hf_version_minor = -1;
-static int hf_request_code = -1;
-static int hf_supported_minor_version = -1;
-static int hf_number_nonsupported_options = -1;
-static int hf_nonsupported_option = -1;
-static int hf_parameter_name = -1;
-static int hf_parameter_value = -1;
-static int hf_query = -1;
-static int hf_authtype = -1;
-static int hf_passwd = -1;
-static int hf_salt = -1;
-static int hf_gssapi_sspi_data = -1;
-static int hf_sasl_auth_mech = -1;
-static int hf_sasl_auth_data = -1;
-static int hf_sasl_auth_data_length = -1;
-static int hf_statement = -1;
-static int hf_portal = -1;
-static int hf_return = -1;
-static int hf_tag = -1;
-static int hf_status = -1;
-static int hf_copydata = -1;
-static int hf_error = -1;
-static int hf_pid = -1;
-static int hf_key = -1;
-static int hf_condition = -1;
-static int hf_text = -1;
-static int hf_tableoid = -1;
-static int hf_typeoid = -1;
-static int hf_oid = -1;
-static int hf_format = -1;
-static int hf_field_count = -1;
-static int hf_val_name = -1;
-static int hf_val_idx = -1;
-static int hf_val_length = -1;
-static int hf_val_data = -1;
-static int hf_val_mod = -1;
-static int hf_severity = -1;
-static int hf_code = -1;
-static int hf_message = -1;
-static int hf_detail = -1;
-static int hf_hint = -1;
-static int hf_position = -1;
-static int hf_internal_position = -1;
-static int hf_internal_query = -1;
-static int hf_where = -1;
-static int hf_schema_name = -1;
-static int hf_table_name = -1;
-static int hf_column_name = -1;
-static int hf_type_name = -1;
-static int hf_constraint_name = -1;
-static int hf_file = -1;
-static int hf_line = -1;
-static int hf_routine = -1;
-static int hf_ssl_response = -1;
-static int hf_gssenc_response = -1;
-static int hf_gssapi_encrypted_payload = -1;
-
-static gint ett_pgsql = -1;
-static gint ett_values = -1;
+static int proto_pgsql;
+static int hf_frontend;
+static int hf_type;
+static int hf_length;
+static int hf_version_major;
+static int hf_version_minor;
+static int hf_request_code;
+static int hf_supported_minor_version;
+static int hf_number_nonsupported_options;
+static int hf_nonsupported_option;
+static int hf_parameter_name;
+static int hf_parameter_value;
+static int hf_query;
+static int hf_authtype;
+static int hf_passwd;
+static int hf_salt;
+static int hf_gssapi_sspi_data;
+static int hf_sasl_auth_mech;
+static int hf_sasl_auth_data;
+static int hf_sasl_auth_data_length;
+static int hf_statement;
+static int hf_portal;
+static int hf_return;
+static int hf_tag;
+static int hf_status;
+static int hf_copydata;
+static int hf_error;
+static int hf_pid;
+static int hf_key;
+static int hf_condition;
+static int hf_text;
+static int hf_tableoid;
+static int hf_typeoid;
+static int hf_oid;
+static int hf_format;
+static int hf_field_count;
+static int hf_val_name;
+static int hf_val_idx;
+static int hf_val_length;
+static int hf_val_data;
+static int hf_val_mod;
+static int hf_severity;
+static int hf_code;
+static int hf_message;
+static int hf_detail;
+static int hf_hint;
+static int hf_position;
+static int hf_internal_position;
+static int hf_internal_query;
+static int hf_where;
+static int hf_schema_name;
+static int hf_table_name;
+static int hf_column_name;
+static int hf_type_name;
+static int hf_constraint_name;
+static int hf_file;
+static int hf_line;
+static int hf_routine;
+static int hf_ssl_response;
+static int hf_gssenc_response;
+static int hf_gssapi_encrypted_payload;
+
+static int ett_pgsql;
+static int ett_values;
#define PGSQL_PORT 5432
-static gboolean pgsql_desegment = TRUE;
-static gboolean first_message = TRUE;
+static bool pgsql_desegment = true;
+static bool first_message = true;
typedef enum {
/* Reserve 0 (== GPOINTER_TO_UINT(NULL)) for no PGSQL detected */
PGSQL_AUTH_STATE_NONE = 1, /* No authentication seen or used */
PGSQL_AUTH_SASL_REQUESTED, /* Server sends SASL auth request with supported SASL mechanisms*/
- PGSQL_AUTH_SASL_CONTINUE, /* Server and/or client send further SASL challange-response messages */
+ PGSQL_AUTH_SASL_CONTINUE, /* Server and/or client send further SASL challenge-response messages */
PGSQL_AUTH_GSSAPI_SSPI_DATA, /* GSSAPI/SSPI in use */
PGSQL_AUTH_SSL_REQUESTED, /* Client sends SSL encryption request */
PGSQL_AUTH_GSSENC_REQUESTED, /* Client sends GSSAPI encryption request */
@@ -108,7 +108,7 @@ typedef enum {
typedef struct pgsql_conn_data {
wmem_tree_t *state_tree; /* Tree of encryption and auth state changes */
- guint32 server_port;
+ uint32_t server_port;
} pgsql_conn_data_t;
static const value_string fe_messages[] = {
@@ -223,15 +223,15 @@ static const value_string gssenc_response_vals[] = {
{ 0, NULL }
};
-static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
- gint n, proto_tree *tree, packet_info *pinfo,
+static void dissect_pgsql_fe_msg(unsigned char type, unsigned length, tvbuff_t *tvb,
+ int n, proto_tree *tree, packet_info *pinfo,
pgsql_conn_data_t *conv_data)
{
- guchar c;
- gint i, siz;
+ unsigned char c;
+ int i, siz;
char *s;
proto_tree *shrub;
- gint32 data_length;
+ int32_t data_length;
pgsql_auth_state_t state;
tvbuff_t *next_tvb;
dissector_handle_t payload_handle;
@@ -368,7 +368,7 @@ static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
/* Describe, Close */
case 'D':
case 'C':
- c = tvb_get_guint8(tvb, n);
+ c = tvb_get_uint8(tvb, n);
if (c == 'P')
i = hf_portal;
else
@@ -401,7 +401,7 @@ static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
length -= i;
n += siz+i;
- if (length == 1 && tvb_get_guint8(tvb, n) == 0)
+ if (length == 1 && tvb_get_uint8(tvb, n) == 0)
break;
}
break;
@@ -469,17 +469,17 @@ static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
}
-static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
- gint n, proto_tree *tree, packet_info *pinfo,
+static void dissect_pgsql_be_msg(unsigned char type, unsigned length, tvbuff_t *tvb,
+ int n, proto_tree *tree, packet_info *pinfo,
pgsql_conn_data_t *conv_data)
{
- guchar c;
- gint i, siz;
+ unsigned char c;
+ int i, siz;
char *s, *t;
- gint32 num_nonsupported_options;
+ int32_t num_nonsupported_options;
proto_item *ti;
proto_tree *shrub;
- guint32 auth_type;
+ uint32_t auth_type;
switch (type) {
/* Authentication request */
@@ -502,7 +502,7 @@ static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
case PGSQL_AUTH_TYPE_SASL:
wmem_tree_insert32(conv_data->state_tree, pinfo->num, GUINT_TO_POINTER(PGSQL_AUTH_SASL_REQUESTED));
n += 4;
- while ((guint)n < length) {
+ while ((unsigned)n < length) {
siz = tvb_strsize(tvb, n);
proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII);
n += siz;
@@ -512,7 +512,7 @@ static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
case PGSQL_AUTH_TYPE_SASL_COMPLETE:
wmem_tree_insert32(conv_data->state_tree, pinfo->num, GUINT_TO_POINTER(PGSQL_AUTH_SASL_CONTINUE));
n += 4;
- if ((guint)n < length) {
+ if ((unsigned)n < length) {
proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA);
}
break;
@@ -605,9 +605,10 @@ static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
case 'N':
length -= 4;
while ((signed)length > 0) {
- c = tvb_get_guint8(tvb, n);
+ c = tvb_get_uint8(tvb, n);
if (c == '\0')
break;
+ --length;
s = tvb_get_stringz_enc(pinfo->pool, tvb, n+1, &siz, ENC_ASCII);
i = hf_text;
switch (c) {
@@ -692,16 +693,16 @@ static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
/* This function is called by tcp_dissect_pdus() to find the size of the
message starting at tvb[offset]. */
-static guint
+static unsigned
pgsql_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
- gint n = 0;
- guchar type;
- guint length;
+ int n = 0;
+ unsigned char type;
+ unsigned length;
/* The length is either the four bytes after the type, or, if the
type is 0, the first four bytes. */
- type = tvb_get_guint8(tvb, offset);
+ type = tvb_get_uint8(tvb, offset);
if (type != '\0')
n = 1;
length = tvb_get_ntohl(tvb, offset+n);
@@ -710,7 +711,7 @@ pgsql_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
/* This function is called by tcp_dissect_pdus() to find the size of the
wrapped GSS-API message starting at tvb[offset] whe. */
-static guint
+static unsigned
pgsql_gssapi_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
/* The length of the GSS-API message is the first four bytes, and does
@@ -730,11 +731,11 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
pgsql_conn_data_t *conn_data;
pgsql_auth_state_t state;
- gint n;
- guchar type;
+ int n;
+ unsigned char type;
const char *typestr;
- guint length;
- gboolean fe;
+ unsigned length;
+ bool fe;
conversation = find_or_create_conversation(pinfo);
conn_data = (pgsql_conn_data_t *)conversation_get_proto_data(conversation, proto_pgsql);
@@ -749,7 +750,7 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
fe = (conn_data->server_port == pinfo->destport);
n = 0;
- type = tvb_get_guint8(tvb, 0);
+ type = tvb_get_uint8(tvb, 0);
if (type != '\0')
n += 1;
length = tvb_get_ntohl(tvb, n);
@@ -762,7 +763,7 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
We identify them by the fact that the first byte of their length
must be zero, and that the next four bytes are a unique tag. */
if (type == '\0') {
- guint tag = tvb_get_ntohl(tvb, 4);
+ unsigned tag = tvb_get_ntohl(tvb, 4);
if (length == 16 && tag == PGSQL_CANCELREQUEST)
typestr = "Cancel request";
@@ -802,7 +803,7 @@ dissect_pgsql_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
done any better? */
col_append_fstr(pinfo->cinfo, COL_INFO, "%s%c",
( first_message ? "" : "/" ), g_ascii_isprint(type) ? type : '?');
- first_message = FALSE;
+ first_message = false;
{
ti = proto_tree_add_item(tree, proto_pgsql, tvb, 0, -1, ENC_NA);
@@ -847,7 +848,7 @@ dissect_pgsql_gssapi_wrap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
conversation_add_proto_data(conversation, proto_pgsql, conn_data);
}
- gboolean fe = (pinfo->destport == conn_data->server_port);
+ bool fe = (pinfo->destport == conn_data->server_port);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGSQL");
col_set_str(pinfo->cinfo, COL_INFO,
@@ -871,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. */
return tvb_captured_length(tvb);
}
- if (encrypt.gssapi_decrypted_tvb) {
- tvbuff_t *decr_tvb = encrypt.gssapi_decrypted_tvb;
- add_new_data_source(pinfo, encrypt.gssapi_decrypted_tvb, "Decrypted GSS-API");
- dissect_pgsql_msg(decr_tvb, pinfo, ptree, data);
- } else if (encrypt.gssapi_data_encrypted) {
- /* Encrypted but couldn't be decrypted. */
- proto_tree_add_item(ptree, hf_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
+ if (encrypt.gssapi_data_encrypted) {
+ if (encrypt.gssapi_decrypted_tvb) {
+ tvbuff_t *decr_tvb = encrypt.gssapi_decrypted_tvb;
+ add_new_data_source(pinfo, encrypt.gssapi_decrypted_tvb, "Decrypted GSS-API");
+ dissect_pgsql_msg(decr_tvb, pinfo, ptree, data);
+ } else {
+ /* Encrypted but couldn't be decrypted. */
+ proto_tree_add_item(ptree, hf_gssapi_encrypted_payload, gssapi_tvb, ver_len, -1, ENC_NA);
+ }
} else {
/* No encrypted (sealed) payload. If any bytes are left, that is
* signed-only payload. */
- if (tvb_reported_length_remaining(gssapi_tvb, ver_len)) {
- dissect_pgsql_msg(tvb_new_subset_remaining(gssapi_tvb, ver_len), pinfo, ptree, data);
+ tvbuff_t *plain_tvb;
+ 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);
@@ -909,12 +918,24 @@ dissect_pgsql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
pgsql_conn_data_t *conn_data;
pgsql_auth_state_t state;
- first_message = TRUE;
+ first_message = true;
conversation = find_or_create_conversation(pinfo);
conn_data = (pgsql_conn_data_t *)conversation_get_proto_data(conversation, proto_pgsql);
- if (!tvb_ascii_isprint(tvb, 0, 1) && tvb_get_guint8(tvb, 0) != '\0') {
+ bool fe = (pinfo->match_uint == pinfo->destport);
+
+ if (fe && tvb_get_uint8(tvb, 0) == 0x16 &&
+ (!conn_data || wmem_tree_lookup32_le(conn_data->state_tree, pinfo->num) == NULL))
+ {
+ /* This is the first message in the conversation, and it looks
+ * like a TLS handshake. Assume the client is performing
+ * "direct SSL" negotiation.
+ */
+ tls_set_appdata_dissector(tls_handle, pinfo, pgsql_handle);
+ }
+
+ if (!tvb_ascii_isprint(tvb, 0, 1) && tvb_get_uint8(tvb, 0) != '\0') {
/* Doesn't look like the start of a PostgreSQL packet. Have we
* seen Postgres yet?
*/
@@ -933,8 +954,6 @@ dissect_pgsql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
*/
}
- gboolean fe = (pinfo->match_uint == pinfo->destport);
-
col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGSQL");
col_set_str(pinfo->cinfo, COL_INFO,
fe ? ">" : "<");
@@ -948,7 +967,7 @@ dissect_pgsql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
ptree = proto_item_add_subtree(ti, ett_pgsql);
proto_tree_add_string(ptree, hf_type, tvb, 0, 0, "SSL response");
proto_tree_add_item(ptree, hf_ssl_response, tvb, 0, 1, ENC_NA);
- switch (tvb_get_guint8(tvb, 0)) {
+ switch (tvb_get_uint8(tvb, 0)) {
case 'S': /* Willing to perform SSL */
/* Next packet will start using SSL. */
ssl_starttls_ack(tls_handle, pinfo, pgsql_handle);
@@ -976,7 +995,7 @@ dissect_pgsql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
ptree = proto_item_add_subtree(ti, ett_pgsql);
proto_tree_add_string(ptree, hf_type, tvb, 0, 0, "GSS encrypt response");
proto_tree_add_item(ptree, hf_gssenc_response, tvb, 0, 1, ENC_NA);
- switch (tvb_get_guint8(tvb, 0)) {
+ switch (tvb_get_uint8(tvb, 0)) {
case 'E': /* ErrorResponse; server does not support GSSAPI. */
/* Process normally. */
tcp_dissect_pdus(tvb, pinfo, tree, pgsql_desegment, 5,
@@ -1253,7 +1272,7 @@ proto_register_pgsql(void)
},
};
- static gint *ett[] = {
+ static int *ett[] = {
&ett_pgsql,
&ett_values
};