Ethereal-dev: [Ethereal-dev] patch for SSH Version 1 support
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Huagang Xie <xie@xxxxxxxx>
Date: Mon, 27 Jan 2003 22:08:34 -0800
Hello, Here is the patch to support SSH version 1 dissection support, it include, - added ssh version 1 support - fixed desegmentation length checking bug - seperated the disection for ssh v2 and v1 Enjoy it, Huagang -- LIDS secure linux kernel http://www.lids.org/ 1024D/B6EFB028 4731 2BF7 7735 4DBD 3771 4E24 B53B B60A B6EF B028
Index: packet-ssh.c
===================================================================
RCS file: /cvsroot/ethereal/packet-ssh.c,v
retrieving revision 1.2
diff -u -r1.2 packet-ssh.c
--- packet-ssh.c 27 Jan 2003 19:40:55 -0000 1.2
+++ packet-ssh.c 28 Jan 2003 06:01:16 -0000
@@ -26,7 +26,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
- * Note: only support SSHv2 now.
+ * Note: support SSH v1 and v2 now.
*
*/
@@ -69,6 +69,15 @@
#define SSH2_MSG_KEX_DH_GEX_REPLY 33
#define SSH2_MSG_KEX_DH_GEX_REQUEST 34
+/* SSH Version 1 definition , from openssh ssh1.h */
+
+#define SSH_MSG_NONE 0 /* no message */
+#define SSH_MSG_DISCONNECT 1 /* cause (string) */
+#define SSH_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */
+#define SSH_CMSG_SESSION_KEY 3 /* key (BIGNUM) */
+#define SSH_CMSG_USER 4 /* user (string) */
+
+
#define SSH_VERSION_UNKNOWN 0
#define SSH_VERSION_1 1
#define SSH_VERSION_2 2
@@ -122,12 +131,13 @@
static gint ett_ssh = -1;
static gint ett_key_exchange= -1;
static gint ett_key_init= -1;
+static gint ett_ssh1= -1;
static gboolean ssh_desegment = TRUE;
#define TCP_PORT_SSH 22
-static const value_string ssh_msg_vals[] = {
+static const value_string ssh2_msg_vals[] = {
{SSH2_MSG_DISCONNECT, "Disconnect"},
{SSH2_MSG_IGNORE, "Ignore"},
{SSH2_MSG_UNIMPLEMENTED, "Unimplemented"},
@@ -144,6 +154,14 @@
{ 0, NULL }
};
+static const value_string ssh1_msg_vals[] = {
+ {SSH_MSG_NONE,"No Message"},
+ {SSH_MSG_DISCONNECT, "Disconnect"},
+ {SSH_SMSG_PUBLIC_KEY,"Public Key"},
+ {SSH_CMSG_SESSION_KEY,"Session Key"},
+ {SSH_CMSG_USER,"User"},
+};
+
static const value_string ssh_opcode_vals[] = {
{ 0, NULL }
@@ -151,6 +169,12 @@
static int ssh_dissect_key_init(tvbuff_t *tvb, int offset, proto_tree *tree);
+static int ssh_dissect_ssh1(tvbuff_t *tvb, packet_info *pinfo,
+ int offset, proto_tree *tree,int is_response,
+ int number, gboolean *need_desegmentation);
+static int ssh_dissect_ssh2(tvbuff_t *tvb, packet_info *pinfo,
+ int offset, proto_tree *tree,int is_response,
+ int number, gboolean *need_desegmentation );
static int ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo,
int offset, proto_tree *tree,int is_response,
int number, gboolean *need_desegmentation );
@@ -262,18 +286,17 @@
}
}
- /* we will not decode SSH1 now */
- if(this_data->counter != 0 && version != SSH_VERSION_2) {
+ if(this_data->counter != 0 && version == SSH_VERSION_UNKNOWN) {
offset = ssh_dissect_encrypted_packet(tvb, pinfo,
offset,ssh_tree,is_response);
return;
}
while((remain_length = tvb_reported_length_remaining(tvb,offset))> 0 ) {
-
need_desegmentation = FALSE;
last_offset = offset;
this_number = this_data->counter+number;
+
if(number > 1 && is_newdata) {
/* update the this_data and flow_data */
if(is_response) {
@@ -284,29 +307,131 @@
}
number++;
-
if(this_number == 0) {
- offset = ssh_dissect_protocol(tvb, pinfo,offset,ssh_tree,
- is_response,&version, &need_desegmentation);
+ offset = ssh_dissect_protocol(tvb, pinfo,
+ offset,ssh_tree, is_response,
+ &version, &need_desegmentation);
if(!is_response) {
global_data->version= version;
}
} else {
- /* response, 1, 2 is key_exchange */
- /* request, 1,2,3,4 is key_exchange */
- if((is_response && this_number > 3) || (!is_response && this_number>4)) {
- offset = ssh_dissect_encrypted_packet(tvb, pinfo,
- offset,ssh_tree,is_response);
- } else {
- offset = ssh_dissect_key_exchange(tvb,pinfo,
+ if(version == SSH_VERSION_1) {
+ offset = ssh_dissect_ssh1(tvb, pinfo,
+ offset,ssh_tree,is_response,this_number,
+ &need_desegmentation);
+ } else if(version == SSH_VERSION_2) {
+ offset = ssh_dissect_ssh2(tvb, pinfo,
offset,ssh_tree,is_response,this_number,
&need_desegmentation);
}
}
+
if(need_desegmentation) return;
}
}
+static int
+ssh_dissect_ssh2(tvbuff_t *tvb, packet_info *pinfo,
+ int offset, proto_tree *tree,int is_response, int this_number,
+ gboolean *need_desegmentation)
+{
+
+ if((is_response && this_number > 3) || (!is_response && this_number>4)) {
+ offset = ssh_dissect_encrypted_packet(tvb, pinfo,
+ offset,tree,is_response);
+ } else {
+ offset = ssh_dissect_key_exchange(tvb,pinfo,
+ offset,tree,is_response,this_number,
+ need_desegmentation);
+ }
+
+ return offset;
+}
+static int
+ssh_dissect_ssh1(tvbuff_t *tvb, packet_info *pinfo,
+ int offset, proto_tree *tree,int is_response,
+ int number, gboolean *need_desegmentation)
+{
+ guint plen, padding_length,len;
+ guint8 msg_code;
+ guint remain_length=0;
+
+ proto_item *tf;
+ proto_item *ssh1_tree =NULL;
+
+ if (ssh_desegment && pinfo->can_desegment) {
+ remain_length = tvb_reported_length_remaining(tvb,offset);
+ if(remain_length < 4) {
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = 4-remain_length;
+ *need_desegmentation = TRUE;
+ return offset;
+ }
+ }
+ plen = tvb_get_ntohl(tvb, offset) ;
+
+ padding_length = 8 - plen%8;
+ if (ssh_desegment && pinfo->can_desegment) {
+ if(plen+4+padding_length > remain_length ) {
+ pinfo->desegment_offset = offset;
+ pinfo->desegment_len = plen+padding_length - remain_length;
+ *need_desegmentation = TRUE;
+ return offset;
+ }
+ }
+
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s: ",
+ is_response?"Server":"Client");
+ }
+
+ if (tree) {
+ proto_tree_add_uint(tree, hf_ssh_packet_length, tvb,
+ offset, 4, plen);
+ }
+ offset+=4;
+/* padding length */
+
+ if (tree) {
+ proto_tree_add_uint(tree, hf_ssh_padding_length, tvb,
+ offset, padding_length, padding_length);
+ }
+ offset += padding_length;
+
+ if(tree) {
+ tf=proto_tree_add_text(tree,tvb,offset,-1,"SSH Version 1");
+ ssh1_tree = proto_item_add_subtree(tf ,ett_ssh1);
+ }
+ /* msg_code */
+ if(number == 1 ) {
+ msg_code = tvb_get_guint8(tvb, offset);
+ if (tree) {
+ proto_tree_add_uint_format(ssh1_tree, hf_ssh_msg_code, tvb,
+ offset, 1, msg_code,"Msg code: %s (%u)",
+ val_to_str(msg_code, ssh1_msg_vals, "Unknown (%u)"),
+ msg_code);
+ }
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
+ val_to_str(msg_code, ssh1_msg_vals, "Unknown (%u)"));
+ }
+ offset += 1;
+ len = plen -1;
+ } else {
+ len = plen;
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, "Encrypted packet len %d", len);
+ }
+ }
+ /* payload */
+ if (tree) {
+ proto_tree_add_item(ssh1_tree, hf_ssh_payload,
+ tvb, offset, len, FALSE);
+ }
+ offset+=len;
+
+ return offset;
+}
static int
ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo,
@@ -334,7 +459,7 @@
plen = tvb_get_ntohl(tvb, offset) ;
if (ssh_desegment && pinfo->can_desegment) {
- if(plen < remain_length - 4 ) {
+ if(plen +4 > remain_length ) {
pinfo->desegment_offset = offset;
pinfo->desegment_len = plen+4 - remain_length;
*need_desegmentation = TRUE;
@@ -369,13 +494,13 @@
if (tree) {
proto_tree_add_uint_format(key_ex_tree, hf_ssh_msg_code, tvb,
offset, 1, msg_code,"Msg code: %s (%u)",
- val_to_str(msg_code, ssh_msg_vals, "Unknown (%u)"),
+ val_to_str(msg_code, ssh2_msg_vals, "Unknown (%u)"),
msg_code);
}
if (check_col(pinfo->cinfo, COL_INFO)) {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
- val_to_str(msg_code, ssh_msg_vals, "Unknown (%u)"));
+ val_to_str(msg_code, ssh2_msg_vals, "Unknown (%u)"));
}
offset += 1;
@@ -450,9 +575,11 @@
}
if(!is_response) {
- if(tvb_strncaseeql(tvb,offset,"SSH-2.",6) == 0 ) {
+ if(tvb_strncaseeql(tvb,offset,"SSH-2.",6) == 0 ) {
+ *(version) = SSH_VERSION_2;
+ }else if(tvb_strncaseeql(tvb,offset,"SSH-1.99-",9) == 0 ) {
*(version) = SSH_VERSION_2;
- }else if(tvb_strncaseeql(tvb,offset,"SSH-1.",6) == 0 ) {
+ }else if(tvb_strncaseeql(tvb,offset,"SSH-1.",6) == 0 ) {
*(version) = SSH_VERSION_1;
}
}
@@ -788,6 +915,7 @@
static gint *ett[] = {
&ett_ssh,
&ett_key_exchange,
+ &ett_ssh1,
&ett_key_init
};
module_t *ssh_module;
Attachment:
pgpey8IAbEe2c.pgp
Description: PGP signature
- Follow-Ups:
- Re: [Ethereal-dev] patch for SSH Version 1 support
- From: Guy Harris
- Re: [Ethereal-dev] patch for SSH Version 1 support
- From: Yaniv Kaul
- Re: [Ethereal-dev] patch for SSH Version 1 support
- Prev by Date: Re: [Ethereal-dev] BGP patches
- Next by Date: Re: [Ethereal-dev] Re: dce rpc type packets
- Previous by thread: Re: [Ethereal-dev] BGP patches
- Next by thread: Re: [Ethereal-dev] patch for SSH Version 1 support
- Index(es):





