summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-openvpn.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:53 +0000
commita86c5f7cae7ec9a3398300555a0b644689d946a1 (patch)
tree39fe4b107c71174fd1e8a8ceb9a4d2aa14116248 /epan/dissectors/packet-openvpn.c
parentReleasing progress-linux version 4.2.6-1~progress7.99u1. (diff)
downloadwireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.tar.xz
wireshark-a86c5f7cae7ec9a3398300555a0b644689d946a1.zip
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-openvpn.c')
-rw-r--r--epan/dissectors/packet-openvpn.c247
1 files changed, 96 insertions, 151 deletions
diff --git a/epan/dissectors/packet-openvpn.c b/epan/dissectors/packet-openvpn.c
index 17e59e50..5727b7b9 100644
--- a/epan/dissectors/packet-openvpn.c
+++ b/epan/dissectors/packet-openvpn.c
@@ -21,6 +21,7 @@
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/reassemble.h>
+#include <epan/conversation.h>
#include "packet-tcp.h"
void proto_register_openvpn(void);
@@ -50,29 +51,29 @@ void proto_reg_handoff_openvpn(void);
#define P_CONTROL_HARD_RESET_CLIENT_V3 10
#define P_CONTROL_WKC_V1 11
-static gint ett_openvpn = -1;
-static gint ett_openvpn_data = -1;
-static gint ett_openvpn_packetarray = -1;
-static gint ett_openvpn_type = -1;
-static gint ett_openvpn_wkc = -1;
-static gint hf_openvpn_data = -1;
-static gint hf_openvpn_wkc_data = -1;
-static gint hf_openvpn_wkc_length = -1;
-static gint hf_openvpn_fragment_bytes = -1;
-static gint hf_openvpn_hmac = -1;
-static gint hf_openvpn_keyid = -1;
-static gint hf_openvpn_mpid = -1;
-static gint hf_openvpn_mpid_arrayelement = -1;
-static gint hf_openvpn_mpid_arraylength = -1;
-static gint hf_openvpn_net_time = -1;
-static gint hf_openvpn_opcode = -1;
-static gint hf_openvpn_pdu_type = -1;
-static gint hf_openvpn_pid = -1;
-static gint hf_openvpn_plen = -1;
-static gint hf_openvpn_rsessionid = -1;
-static gint hf_openvpn_sessionid = -1;
-static gint hf_openvpn_peerid = -1;
-static gint proto_openvpn = -1;
+static int ett_openvpn;
+static int ett_openvpn_data;
+static int ett_openvpn_packetarray;
+static int ett_openvpn_type;
+static int ett_openvpn_wkc;
+static int hf_openvpn_data;
+static int hf_openvpn_wkc_data;
+static int hf_openvpn_wkc_length;
+static int hf_openvpn_fragment_bytes;
+static int hf_openvpn_hmac;
+static int hf_openvpn_keyid;
+static int hf_openvpn_mpid;
+static int hf_openvpn_mpid_arrayelement;
+static int hf_openvpn_mpid_arraylength;
+static int hf_openvpn_net_time;
+static int hf_openvpn_opcode;
+static int hf_openvpn_pdu_type;
+static int hf_openvpn_pid;
+static int hf_openvpn_plen;
+static int hf_openvpn_rsessionid;
+static int hf_openvpn_sessionid;
+static int hf_openvpn_peerid;
+static int proto_openvpn;
static dissector_handle_t openvpn_udp_handle;
static dissector_handle_t openvpn_tcp_handle;
@@ -80,11 +81,11 @@ static dissector_handle_t openvpn_tcp_handle;
static dissector_handle_t tls_handle;
/* Preferences */
-static gboolean pref_long_format = TRUE;
-static gboolean pref_tls_auth = FALSE;
-static gboolean pref_tls_auth_override = FALSE;
-static gboolean pref_tls_crypt_override = FALSE;
-static guint tls_auth_hmac_size = 20; /* Default SHA-1 160 Bits */
+static bool pref_long_format = true;
+static bool pref_tls_auth;
+static bool pref_tls_auth_override;
+static bool pref_tls_crypt_override;
+static unsigned tls_auth_hmac_size = 20; /* Default SHA-1 160 Bits */
static const value_string openvpn_message_types[] =
{
@@ -105,18 +106,18 @@ static const value_string openvpn_message_types[] =
/* everything used during the reassembly process */
static reassembly_table msg_reassembly_table;
-static gint ett_openvpn_fragment = -1;
-static gint ett_openvpn_fragments = -1;
-static gint hf_openvpn_fragment = -1;
-static gint hf_openvpn_fragment_count = -1;
-static gint hf_openvpn_fragment_error = -1;
-static gint hf_openvpn_fragment_multiple_tails = -1;
-static gint hf_openvpn_fragment_overlap = -1;
-static gint hf_openvpn_fragment_overlap_conflicts = -1;
-static gint hf_openvpn_fragment_too_long_fragment = -1;
-static gint hf_openvpn_fragments = -1;
-static gint hf_openvpn_reassembled_in = -1;
-static gint hf_openvpn_reassembled_length = -1;
+static int ett_openvpn_fragment;
+static int ett_openvpn_fragments;
+static int hf_openvpn_fragment;
+static int hf_openvpn_fragment_count;
+static int hf_openvpn_fragment_error;
+static int hf_openvpn_fragment_multiple_tails;
+static int hf_openvpn_fragment_overlap;
+static int hf_openvpn_fragment_overlap_conflicts;
+static int hf_openvpn_fragment_too_long_fragment;
+static int hf_openvpn_fragments;
+static int hf_openvpn_reassembled_in;
+static int hf_openvpn_reassembled_length;
static const fragment_items openvpn_frag_items = {
/* Fragment subtrees */
@@ -144,11 +145,11 @@ static const fragment_items openvpn_frag_items = {
/* we check the leading 4 byte of a suspected hmac for 0x00 bytes,
if more than 1 byte out of the 4 provided contains 0x00, the
hmac is considered not valid, which suggests that no tls auth is used.
- unfortunatly there is no other way to detect tls auth on the fly */
-static gboolean
-check_for_valid_hmac(guint32 hmac)
+ unfortunately there is no other way to detect tls auth on the fly */
+static bool
+check_for_valid_hmac(uint32_t hmac)
{
- gint c = 0;
+ int c = 0;
if ((hmac & 0x000000FF) == 0x00000000) {
c++;
}
@@ -162,30 +163,25 @@ check_for_valid_hmac(guint32 hmac)
c++;
}
if (c > 1) {
- return FALSE;
+ return false;
} else {
- return TRUE;
+ return true;
}
}
static int
-dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvpn_tree, proto_tree *parent_tree, gint offset)
+dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvpn_tree, proto_tree *parent_tree, int offset)
{
- gboolean tls_auth;
- gboolean tls_crypt = FALSE;
- guint openvpn_keyid;
- guint openvpn_opcode;
- guint32 msg_mpid = -1;
- guint32 msg_sessionid = -1;
- guint8 openvpn_predict_tlsauth_arraylength;
+ bool tls_auth;
+ bool tls_crypt = false;
+ unsigned openvpn_keyid;
+ unsigned openvpn_opcode;
+ uint32_t msg_sessionid = -1;
+ uint8_t openvpn_predict_tlsauth_arraylength;
proto_item *ti2;
proto_tree *packetarray_tree, *type_tree;
- guint32 msg_length_remaining;
- gboolean msg_lastframe;
- fragment_head *frag_msg;
- tvbuff_t *new_tvb;
- gboolean save_fragmented;
- gint wkc_offset = -1;
+ uint32_t msg_length_remaining;
+ int wkc_offset = -1;
/* Clear out stuff in the info column */
col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
@@ -222,54 +218,54 @@ dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvp
offset += 8;
/* tls-auth detection (this can be overridden by preferences */
- openvpn_predict_tlsauth_arraylength = tvb_get_guint8(tvb, offset);
+ openvpn_predict_tlsauth_arraylength = tvb_get_uint8(tvb, offset);
/* if the first 4 bytes that would, if tls-auth is used, contain part of the hmac,
lack entropy, we assume no tls-auth is used */
- if (pref_tls_auth_override == FALSE) {
+ if (pref_tls_auth_override == false) {
if ((openvpn_opcode != P_DATA_V1)
&& (openvpn_predict_tlsauth_arraylength > 0)
&& check_for_valid_hmac(tvb_get_ntohl(tvb, offset))) {
- tls_auth = TRUE;
+ tls_auth = true;
} else {
- tls_auth = FALSE;
+ tls_auth = false;
}
} else {
tls_auth = pref_tls_auth;
}
- if (openvpn_opcode == P_CONTROL_HARD_RESET_CLIENT_V3 || openvpn_opcode == P_CONTROL_WKC_V1 || pref_tls_crypt_override == TRUE) {
+ if (openvpn_opcode == P_CONTROL_HARD_RESET_CLIENT_V3 || openvpn_opcode == P_CONTROL_WKC_V1 || pref_tls_crypt_override == true) {
/* these opcodes are always tls-crypt*/
- tls_crypt = TRUE;
- tls_auth = FALSE;
+ tls_crypt = true;
+ tls_auth = false;
}
- if (tls_auth == TRUE) {
+ if (tls_auth == true) {
proto_tree_add_item(openvpn_tree, hf_openvpn_hmac, tvb, offset, tls_auth_hmac_size, ENC_NA);
offset += tls_auth_hmac_size;
}
- if (tls_auth == TRUE || tls_crypt == TRUE) {
+ if (tls_auth == true || tls_crypt == true) {
if (tvb_reported_length_remaining(tvb, offset) >= 8) {
proto_tree_add_item(openvpn_tree, hf_openvpn_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
- if (pref_long_format || tls_crypt == TRUE) {
+ if (pref_long_format || tls_crypt == true) {
proto_tree_add_item(openvpn_tree, hf_openvpn_net_time, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
}
- if (tls_crypt == TRUE) {
+ if (tls_crypt == true) {
/* tls-crypt uses HMAC-SHA256 */
proto_tree_add_item(openvpn_tree, hf_openvpn_hmac, tvb, offset, 32, ENC_NA);
offset += 32;
}
}
- if (tvb_reported_length_remaining(tvb, offset) >= 1 && tls_crypt == FALSE) {
+ if (tvb_reported_length_remaining(tvb, offset) >= 1 && tls_crypt == false) {
/* read P_ACK packet-id array length */
- gint pid_arraylength = tvb_get_guint8(tvb, offset);
- gint i;
+ int pid_arraylength = tvb_get_uint8(tvb, offset);
+ int i;
proto_tree_add_item(openvpn_tree, hf_openvpn_mpid_arraylength, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
@@ -289,10 +285,9 @@ dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvp
}
/* if we have a P_CONTROL packet */
- if (openvpn_opcode != P_ACK_V1 && tls_crypt == FALSE) {
+ if (openvpn_opcode != P_ACK_V1 && tls_crypt == false) {
/* read Message Packet-ID */
if (tvb_reported_length_remaining(tvb, offset) >= 4) {
- msg_mpid = tvb_get_bits32(tvb, offset*8, 32, ENC_BIG_ENDIAN);
proto_tree_add_item(openvpn_tree, hf_openvpn_mpid, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
@@ -306,8 +301,8 @@ dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvp
return tvb_captured_length(tvb);
}
- gint data_len = msg_length_remaining;
- gint wkc_len = -1;
+ int data_len = msg_length_remaining;
+ int wkc_len = -1;
if ((openvpn_opcode == P_CONTROL_HARD_RESET_CLIENT_V3 || openvpn_opcode == P_CONTROL_WKC_V1)
&& msg_length_remaining >= 2) {
@@ -339,80 +334,30 @@ dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvp
return tvb_captured_length(tvb);
}
- /* Try to reassemble */
+ /* Control message, possibly fragmented, carrying TLS. Try to reassemble. */
- /* an ordinary openvpn control packet contains 100 bytes only if it is part of a
- fragmented message and is not the last fragment of the current transmission.
- Note that the tvb contains exactly one openvpn PDU:
- UDP: by definition;
- TCP: because of the use of tcp_dissect_pdus().
- */
- if (msg_length_remaining == 100) {
- msg_lastframe = FALSE;
- } else {
- msg_lastframe = TRUE;
- }
-
- save_fragmented = pinfo->fragmented;
- pinfo->fragmented = TRUE;
-
- frag_msg = fragment_add_seq_next(
- &msg_reassembly_table,
- tvb,
- offset,
- pinfo,
- msg_sessionid, /* ID for fragments belonging together */
- NULL,
- msg_length_remaining, /* fragment length - to the end */
- !(msg_lastframe)); /* More fragments ? */
-
- /* show "data" fragment on tree unless "reassembled" message has just one part. */
- /* i.e., show if ("not reassembled") or ("reassembled" and "has multiple fragments") */
- if ((frag_msg == NULL) || (frag_msg->next != NULL)) {
- proto_tree *data_tree;
- data_tree = proto_tree_add_subtree_format(openvpn_tree, tvb, offset, -1,
- ett_openvpn_data, NULL, "Message fragment (%d bytes)",
- tvb_captured_length_remaining(tvb, offset));
-
- proto_tree_add_item(data_tree, hf_openvpn_fragment_bytes, tvb, offset, -1, ENC_NA);
- }
-
- new_tvb = NULL;
- if (frag_msg) {
- if (msg_lastframe) { /* Reassembled */
- new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message",
- frag_msg, &openvpn_frag_items, NULL, openvpn_tree);
- if (frag_msg->next != NULL) { /* multiple frags ? */
- col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled "); /* overwritten by next dissector */
- }
-
- } else { /* Not last packet of reassembled Short Message */
- col_append_fstr(pinfo->cinfo, COL_INFO, " (Message fragment %d) ", msg_mpid);
- if (pinfo->num != frag_msg->reassembled_in) {
- /* Add a "Reassembled in" link if not reassembled in this frame */
- proto_tree_add_uint(openvpn_tree, hf_openvpn_reassembled_in,
- tvb, 0, 0, frag_msg->reassembled_in);
- }
- }
- } /* if (frag_msg) */
+ streaming_reassembly_info_t *streaming_reassembly_info = NULL;
- pinfo->fragmented = save_fragmented;
-
- /* Now see if we need to call subdissector.
- new_tvb is non-null if we "reassembled* a message (even just one fragment) */
-
- if (new_tvb) {
- /* call SSL/TLS dissector if we just processed the last fragment */
- call_dissector(tls_handle, new_tvb, pinfo, parent_tree);
+ conversation_t *conv = find_or_create_conversation_by_id(pinfo, CONVERSATION_OPENVPN, msg_sessionid);
+ streaming_reassembly_info = conversation_get_proto_data(conv, proto_openvpn);
+ if (!streaming_reassembly_info) {
+ streaming_reassembly_info = streaming_reassembly_info_new();
+ conversation_add_proto_data(conv, proto_openvpn, streaming_reassembly_info);
}
+ reassemble_streaming_data_and_call_subdissector(tvb, pinfo, offset,
+ msg_length_remaining, openvpn_tree, parent_tree, msg_reassembly_table,
+ streaming_reassembly_info, get_virtual_frame_num64(tvb, pinfo, offset),
+ tls_handle, parent_tree, NULL /* should it be tcpinfo if we have it? */, "OpenVPN Message",
+ &openvpn_frag_items, hf_openvpn_fragment_bytes);
+
return tvb_captured_length(tvb);
}
-static guint
-get_msg_length(packet_info *pinfo _U_, tvbuff_t *tvb, gint offset, void *data _U_)
+static unsigned
+get_msg_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
{
- return (guint)tvb_get_ntohs(tvb, offset) + 2; /* length field is at offset 0,
+ return (unsigned)tvb_get_ntohs(tvb, offset) + 2; /* length field is at offset 0,
+2 to account for the length field itself */
}
@@ -434,7 +379,7 @@ static int
dissect_openvpn_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
tcp_dissect_pdus( tvb, pinfo, tree,
- TRUE, /* should data be reassembled? */
+ true, /* should data be reassembled? */
2, /* how much bytes do we need for get_msg_length to be successful,
since the length is the first thing in an openvpn packet we choose 2 */
get_msg_length, /* fptr for function to get the packetlength of current frame */
@@ -574,25 +519,25 @@ proto_register_openvpn(void)
},
{ &hf_openvpn_fragment_overlap,
{ "Message fragment overlap", "openvpn.fragment.overlap",
- FT_BOOLEAN, 0,
+ FT_BOOLEAN, BASE_NONE,
NULL, 0x00,
NULL, HFILL }
},
{ &hf_openvpn_fragment_overlap_conflicts,
{ "Message fragment overlapping with conflicting data", "openvpn.fragment.overlap.conflicts",
- FT_BOOLEAN, 0,
+ FT_BOOLEAN, BASE_NONE,
NULL, 0x00,
NULL, HFILL }
},
{ &hf_openvpn_fragment_multiple_tails,
{ "Message has multiple tail fragments", "openvpn.fragment.multiple_tails",
- FT_BOOLEAN, 0,
+ FT_BOOLEAN, BASE_NONE,
NULL, 0x00,
NULL, HFILL }
},
{ &hf_openvpn_fragment_too_long_fragment,
{ "Message fragment too long", "openvpn.fragment.too_long_fragment",
- FT_BOOLEAN, 0,
+ FT_BOOLEAN, BASE_NONE,
NULL, 0x00,
NULL, HFILL }
},
@@ -623,7 +568,7 @@ proto_register_openvpn(void)
};
/* Setup protocol subtree array */
- static gint *ett[] = {
+ static int *ett[] = {
&ett_openvpn,
&ett_openvpn_type,
&ett_openvpn_data,
@@ -683,7 +628,7 @@ proto_register_openvpn(void)
" is inserted after the HMAC signature."
" This field can either be 4 bytes or 8 bytes including an optional time_t timestamp long.\n"
" This option is only evaluated if tls_auth_hmac_size > 0.\n"
- " The default value is TRUE.",
+ " The default value is true.",
&pref_long_format);
}