Ethereal-dev: [Ethereal-dev] patch for ssh dissector.

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: Sun, 26 Jan 2003 15:55:40 -0800
Norka, Douglas,  

Thanks for your suggestion.

Here is a patch to deal with the problem..

Now, all un-determinable ssh flow will be treated as SSH_VERSION_UNKNOWN. 
here is a patch for it.


Thanks,
Huagang


On Sun, Jan 26, 2003 at 11:32:11AM -0500, Norka Lucena wrote:
> Hi Huagang,
> 
> First of all THANK YOU SO VERY MUCH for the SSH dissector!
> I was planning to do it since I needed badly for some testing. Actually,
> I started but didn't have much. 
> 
> I haven't had the chance to use it yet, though, since I have a deadline
> for tomorrow of something else.
> 
> One of my friends, who is not on the Ethereal list tested it and asked
> me to forward the following message to you. If you need to contact him
> directly, his address is below
> 
> Thanks again, and I hope this is useful to you.
> 
> 
> Norka
> 
> -----Forwarded Message-----
> 
> > From: Douglas F. Calvert <dfc@xxxxxxxxx>
> > To: Norka Lucena <norka@xxxxxxxxxxx>
> > Subject: Re: Got it
> > Date: 25 Jan 2003 22:49:59 -0500
> > 
> > Hello,
> >  I am playing around with the stuff right now. I noticed a problem
> with
> > the ssh dissector in ethereal. Can you forward this problem to the
> > developer and the ethereal development list?
> > 
> > If ethereal watches the ssh connection start up it correctly detects
> the
> > connection and the subsequent data as sshv2. However if it picks up an
> > sshv2 connection midstream it identifies the connection as sshv1.
> Maybe
> > there is no way to differentiate an ssh version once the connection is
> > started but it is problematic that the dissector assumes that it is
> > sshv1. 
> > 
> >   
> 

-- 
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.1
diff -u -r1.1 packet-ssh.c
--- packet-ssh.c	25 Jan 2003 00:22:50 -0000	1.1
+++ packet-ssh.c	26 Jan 2003 23:32:30 -0000
@@ -69,6 +69,10 @@
 #define SSH2_MSG_KEX_DH_GEX_REPLY			33
 #define SSH2_MSG_KEX_DH_GEX_REQUEST			34
 
+#define SSH_VERSION_UNKNOWN 	0
+#define SSH_VERSION_1		1
+#define SSH_VERSION_2		2
+
 /* proto data */
 
 struct ssh_pdu_data{
@@ -79,7 +83,7 @@
 struct ssh_flow_data {
 	guint 	req_counter;
 	guint	rsp_counter;
-	gboolean is_ssh2;
+	guint 	version;
 };
 static GMemChunk *ssh_this_data=NULL;
 static GMemChunk *ssh_global_data = NULL;
@@ -151,7 +155,7 @@
 		int offset, proto_tree *tree,int is_response,
 		int number, gboolean *need_desegmentation );
 static int ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo, 
-		int offset, proto_tree *tree,int is_response,int *is_ssh2,
+		int offset, proto_tree *tree,int is_response,int *version,
 		gboolean *need_desegmentation);
 static int ssh_dissect_encrypted_packet(tvbuff_t *tvb, packet_info *pinfo,
 		int offset, proto_tree *tree,int is_response);
@@ -189,7 +193,7 @@
 	gboolean	is_response;
 	gboolean 	is_newdata;
 	gboolean 	need_desegmentation;
-	gboolean	is_ssh2 ;
+	guint		version;
 
 	struct ssh_pdu_data *this_data=NULL;
 	struct ssh_flow_data *global_data=NULL;
@@ -211,7 +215,7 @@
 		global_data = g_mem_chunk_alloc(ssh_global_data);
 		global_data->req_counter=0;
 		global_data->rsp_counter=0;
-		global_data->is_ssh2=TRUE;
+		global_data->version=SSH_VERSION_UNKNOWN;
 		conversation_add_proto_data(conversation,proto_ssh,global_data);
 	}
 
@@ -241,22 +245,25 @@
 	}
 	number = 0;
 	
-	is_ssh2 = global_data->is_ssh2;
+	version = global_data->version;
 
 	if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
-		if(this_data->counter == 0 ) {
-			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSH");
-		}else {
-			if(is_ssh2) {
-				col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv2");
-			}else {
+		switch(version) {
+			case SSH_VERSION_UNKNOWN:
+				col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSH");
+				break;
+			case SSH_VERSION_1:
 				col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv1");
-			}
+				break;
+			case SSH_VERSION_2:
+				col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv2");
+				break;
+			
 		}
 	}
 
 	/* we will not decode SSH1 now */
-	if(!is_ssh2) {
+	if(this_data->counter != 0 && version != SSH_VERSION_2) {
 		offset = ssh_dissect_encrypted_packet(tvb, pinfo,
 			offset,ssh_tree,is_response);
 		return;
@@ -280,11 +287,11 @@
 	
 		if(this_number == 0)  {
 			offset = ssh_dissect_protocol(tvb, pinfo,offset,ssh_tree,
-					is_response,&is_ssh2, &need_desegmentation);
+					is_response,&version, &need_desegmentation);
 			if(!is_response) {
-				global_data->is_ssh2 = is_ssh2;
+				global_data->version= version;
 			}
-		} else { 
+		} 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)) {
@@ -426,12 +433,30 @@
 	
 static int
 ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo,
-	       	int offset, proto_tree *tree, int is_response, int * is_ssh2,
+	       	int offset, proto_tree *tree, int is_response, int * version,
 		gboolean *need_desegmentation)
 {
 	guint	linelen,next_offset;
 	guint	remain_length;
 	
+	/* 
+	 *  If the first packet do not contain the banner, 
+	 *  it is dump in the middle of a flow or not a ssh at all 
+	 */
+	if(tvb_strncaseeql(tvb,offset,"SSH-",4) != 0 ) {
+		offset = ssh_dissect_encrypted_packet(tvb, pinfo,
+			offset,tree,is_response);
+		return offset;
+	}
+
+	if(!is_response) {
+	       if(tvb_strncaseeql(tvb,offset,"SSH-2.",6) == 0 ) {
+			*(version) = SSH_VERSION_2;
+	       }else if(tvb_strncaseeql(tvb,offset,"SSH-1.",6) == 0 ) {
+			*(version) = SSH_VERSION_1;
+	       }
+	}
+	
 	remain_length = tvb_reported_length_remaining(tvb,offset);
 	linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
 
@@ -453,9 +478,6 @@
 		proto_tree_add_item(tree, hf_ssh_protocol,
 		    		tvb, offset, linelen+1, FALSE);
   	}
-	if(!is_response && tvb_strncaseeql(tvb,offset,"SSH-2.0-",8)) {
-		*(is_ssh2) = FALSE;
-	}
 	offset+=linelen+1;
 	return offset;
 }

Attachment: pgpo5p0DMPTOc.pgp
Description: PGP signature