/**************************************************************************** 
** File: ssh.c
**
** Author: Mike Borella
**
** Comments: SSH protocol module.  
**
** Ok, this is very weak support, but here are the difficulties.  SSH is 
** rather stateful, which means you decode packets based on the contents
** of previous packets.  And I'm not just talking about the crypto, but 
** the protocol itself.  So if you look at an SSH packet midstream, you
** can't read it because of the crypto, but you may not be able to figure
** out *where* certain plaintext fields might be because you don't know if
** it is version 1 or 2.  So I'm not sure what else we can do with this 
** module, but this simple parser is at least a start.
**
** $Id: ssh.c,v 1.8 2006/11/21 07:47:34 farooq-i-azam Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Library General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/

#include "ssh.h"

extern struct arg_t * my_args;

/*----------------------------------------------------------------------------
**
** dump_ssh()
**
** Parse and display SSH packets
**
**----------------------------------------------------------------------------
*/

void dump_ssh(packet_t *pkt)
{
  u_int8_t * payload;
  u_int32_t  size;

  /*
   * SHH doesn't have "message types" or any other neat way of decoding
   * packets in a stateless fashion.  Therefore, we'll just grab the whole
   * damn thing and work from there...
   */

  /* Set the layer */
  set_layer(LAYER_APPLICATION);

  /* find the paylaod size, then allocate memory and read the packet */
  size = get_packet_apparentbytesleft(pkt);
  if (size <= 0)
    return;
  payload = (u_int8_t *) my_malloc (size+1);
  payload[size] = '\0';
  if (get_packet_bytes(payload, pkt, size) == 0)
    {
      my_free(payload);
      return;
    } 

  /* 
   * If the payload is printable, we'll assume that its a string we 
   * can display.  If not, its the binary format version of the message.
   * We subtract 1 to get rid of the \n on the end.
   */

  if (isprint_str(payload, size))
    {
      payload[size-1] = '\0'; /* null terminate over the \n */
      if (my_args->m)
	{
	  display_minimal_string("| ");
	  display_minimal_string(payload);
	}
      else
	{
	  display_header_banner("SSH");
	  display_string("Version", payload);
	}
    }
  else
    {
      if (my_args->m)
	{
	}
      else
	{
	  u_int32_t packet_length;

	  memcpy((void *) &packet_length, payload, 4);
	  packet_length = ntohl(packet_length);

	  display_header_banner("SSH");
	  display("Packet length", (u_int8_t *) &packet_length, 4, DISP_DEC);
	  display("Payload", (u_int8_t *) payload+4, size-4, 
		  DISP_HEX_MULTILINE);
	}
      
    }
  
  /* free memory, of course */
  my_free(payload);
  
  /* dump the hex buffer */
  hexbuffer_flush();

}
