09718fb9b3
Move clang warnings to normal set. Let the CMake compatibility check control the warning. Fix or work-around -Wunreachable warnings in the code.
704 lines
31 KiB
C
704 lines
31 KiB
C
/* packet-sftp.c
|
|
* Routines for ssh packet dissection
|
|
*
|
|
* Jérôme Hamm
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* Copied from packet-ssh.c
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*
|
|
*
|
|
* Note: support for SFTP.
|
|
*
|
|
*/
|
|
|
|
/* SFTP is defined in:
|
|
*
|
|
* draft-ietf-secsh-filexfer-02 - SSH File Transfer Protocol
|
|
*
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
/* Start with WIRESHARK_LOG_DOMAINS=sftp and WIRESHARK_LOG_LEVEL=debug to see messages. */
|
|
#define WS_LOG_DOMAIN "sftp"
|
|
|
|
#include <epan/packet.h>
|
|
#include <epan/expert.h>
|
|
|
|
void proto_register_sftp(void);
|
|
|
|
static int proto_sftp = -1;
|
|
|
|
static int hf_ssh_sftp_len = -1;
|
|
static int hf_ssh_sftp_type = -1;
|
|
static int hf_ssh_sftp_version = -1;
|
|
static int hf_ssh_sftp_id = -1;
|
|
static int hf_ssh_sftp_path_len = -1;
|
|
static int hf_ssh_sftp_path = -1;
|
|
static int hf_ssh_sftp_pflags = -1;
|
|
static int hf_ssh_sftp_name_count = -1;
|
|
static int hf_ssh_sftp_name_fn_len = -1;
|
|
static int hf_ssh_sftp_name_fn = -1;
|
|
static int hf_ssh_sftp_name_ln_len = -1;
|
|
static int hf_ssh_sftp_name_ln = -1;
|
|
static int hf_ssh_sftp_attrs_flags = -1;
|
|
static int hf_ssh_sftp_attrs_size = -1;
|
|
static int hf_ssh_sftp_attrs_uid = -1;
|
|
static int hf_ssh_sftp_attrs_gid = -1;
|
|
static int hf_ssh_sftp_attrs_permissions = -1;
|
|
static int hf_ssh_sftp_attrs_atime = -1;
|
|
static int hf_ssh_sftp_attrs_mtime = -1;
|
|
static int hf_ssh_sftp_attrs_extended_count = -1;
|
|
static int hf_ssh_sftp_handle_len = -1;
|
|
static int hf_ssh_sftp_handle = -1;
|
|
static int hf_ssh_sftp_status = -1;
|
|
static int hf_ssh_sftp_error_message_len = -1;
|
|
static int hf_ssh_sftp_error_message = -1;
|
|
static int hf_ssh_sftp_offset = -1;
|
|
static int hf_ssh_sftp_length = -1;
|
|
static int hf_ssh_sftp_data_len = -1;
|
|
static int hf_ssh_sftp_data = -1;
|
|
static int hf_ssh_lang_tag_length = -1;
|
|
static int hf_ssh_lang_tag = -1;
|
|
|
|
static gint ett_sftp = -1;
|
|
static gint ett_sftp_attrs = -1;
|
|
|
|
static dissector_handle_t sftp_handle;
|
|
|
|
#define SSH_FXP_INIT 1
|
|
#define SSH_FXP_VERSION 2
|
|
#define SSH_FXP_OPEN 3
|
|
#define SSH_FXP_CLOSE 4
|
|
#define SSH_FXP_READ 5
|
|
#define SSH_FXP_WRITE 6
|
|
#define SSH_FXP_LSTAT 7
|
|
#define SSH_FXP_FSTAT 8
|
|
#define SSH_FXP_SETSTAT 9
|
|
#define SSH_FXP_FSETSTAT 10
|
|
#define SSH_FXP_OPENDIR 11
|
|
#define SSH_FXP_READDIR 12
|
|
#define SSH_FXP_REMOVE 13
|
|
#define SSH_FXP_MKDIR 14
|
|
#define SSH_FXP_RMDIR 15
|
|
#define SSH_FXP_REALPATH 16
|
|
#define SSH_FXP_STAT 17
|
|
#define SSH_FXP_RENAME 18
|
|
#define SSH_FXP_READLINK 19
|
|
#define SSH_FXP_LINK 21
|
|
#define SSH_FXP_BLOCK 22
|
|
#define SSH_FXP_UNBLOCK 23
|
|
|
|
#define SSH_FXP_STATUS 101
|
|
#define SSH_FXP_HANDLE 102
|
|
#define SSH_FXP_DATA 103
|
|
#define SSH_FXP_NAME 104
|
|
#define SSH_FXP_ATTRS 105
|
|
|
|
#define SSH_FXP_EXTENDED 200
|
|
#define SSH_FXP_EXTENDED_REPLY 201
|
|
|
|
#define SSH_FILEXFER_ATTR_SIZE 0x00000001
|
|
#define SSH_FILEXFER_ATTR_UIDGID 0x00000002
|
|
#define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
|
|
#define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
|
|
#define SSH_FILEXFER_ATTR_EXTENDED 0x80000000
|
|
|
|
static const value_string ssh2_sftp_vals[] = {
|
|
{SSH_FXP_INIT, "SSH_FXP_INIT"},
|
|
{SSH_FXP_VERSION, "SSH_FXP_VERSION"},
|
|
{SSH_FXP_OPEN, "SSH_FXP_OPEN"},
|
|
{SSH_FXP_CLOSE, "SSH_FXP_CLOSE"},
|
|
{SSH_FXP_READ, "SSH_FXP_READ"},
|
|
{SSH_FXP_WRITE, "SSH_FXP_WRITE"},
|
|
{SSH_FXP_LSTAT, "SSH_FXP_LSTAT"},
|
|
{SSH_FXP_FSTAT, "SSH_FXP_FSTAT"},
|
|
{SSH_FXP_SETSTAT, "SSH_FXP_SETSTAT"},
|
|
{SSH_FXP_FSETSTAT, "SSH_FXP_FSETSTAT"},
|
|
{SSH_FXP_OPENDIR, "SSH_FXP_OPENDIR"},
|
|
{SSH_FXP_READDIR, "SSH_FXP_READDIR"},
|
|
{SSH_FXP_REMOVE, "SSH_FXP_REMOVE"},
|
|
{SSH_FXP_MKDIR, "SSH_FXP_MKDIR"},
|
|
{SSH_FXP_RMDIR, "SSH_FXP_RMDIR"},
|
|
{SSH_FXP_REALPATH, "SSH_FXP_REALPATH"},
|
|
{SSH_FXP_STAT, "SSH_FXP_STAT"},
|
|
{SSH_FXP_RENAME, "SSH_FXP_RENAME"},
|
|
{SSH_FXP_READLINK, "SSH_FXP_READLINK"},
|
|
{SSH_FXP_LINK, "SSH_FXP_LINK"},
|
|
{SSH_FXP_BLOCK, "SSH_FXP_BLOCK"},
|
|
{SSH_FXP_UNBLOCK, "SSH_FXP_UNBLOCK"},
|
|
{SSH_FXP_STATUS, "SSH_FXP_STATUS"},
|
|
{SSH_FXP_HANDLE, "SSH_FXP_HANDLE"},
|
|
{SSH_FXP_DATA, "SSH_FXP_DATA"},
|
|
{SSH_FXP_NAME, "SSH_FXP_NAME"},
|
|
{SSH_FXP_ATTRS, "SSH_FXP_ATTRS"},
|
|
{SSH_FXP_EXTENDED, "SSH_FXP_EXTENDED"},
|
|
{SSH_FXP_EXTENDED_REPLY, "SSH_FXP_EXTENDED_REPLY"},
|
|
{0, NULL}
|
|
};
|
|
|
|
static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
|
|
static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo,
|
|
int offset, proto_item *msg_type_tree);
|
|
|
|
//static int dissect_sftp(tvbuff_t *packet_tvb, packet_info *pinfo,
|
|
// int offset, proto_item *msg_type_tree)
|
|
static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
|
{
|
|
int offset = 0;
|
|
guint plen;
|
|
guint slen;
|
|
plen = tvb_get_ntohl(tvb, offset) ;
|
|
wmem_strbuf_t *title = wmem_strbuf_new(wmem_packet_scope(), "SFTP");
|
|
proto_item * sftp_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_sftp, NULL, NULL);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 typ;
|
|
typ = tvb_get_guint8(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset += 1;
|
|
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(typ, ssh2_sftp_vals, "Unknown (%u)"));
|
|
switch(typ){
|
|
case SSH_FXP_INIT:{
|
|
int ver = tvb_get_ntohl(tvb, offset) ;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_INIT (%d) version %d", typ, ver);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
break;
|
|
}
|
|
case SSH_FXP_VERSION:{
|
|
int ver = tvb_get_ntohl(tvb, offset) ;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_VERSION (%d) version %d", typ, ver);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
break;
|
|
}
|
|
case SSH_FXP_OPEN:{
|
|
int id = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
// int pflags = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_pflags, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_OPEN (%d) id=%d [%s]", typ, id, path);
|
|
break;
|
|
}
|
|
case SSH_FXP_CLOSE:{
|
|
int id = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_CLOSE (%d) id=%d {%s}", typ, id, handle);
|
|
break;
|
|
}
|
|
case SSH_FXP_READ:{
|
|
int id = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
|
|
offset += 8;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_length, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_READ (%d) id=%d {%s}", typ, id, handle);
|
|
break;
|
|
}
|
|
case SSH_FXP_WRITE:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
|
|
offset += 8;
|
|
int dlen = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA);
|
|
offset += dlen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_WRITE (%d) id=%d {%s} len=%d", typ, id, handle, dlen);
|
|
break;
|
|
}
|
|
case SSH_FXP_LSTAT:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_LSTAT (%d) id=%d [%s]", typ, id, path);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
break;
|
|
}
|
|
case SSH_FXP_FSTAT:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_FSTAT (%d) id=%d {%s}", typ, id, handle);
|
|
break;
|
|
}
|
|
case SSH_FXP_SETSTAT:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
|
|
proto_item_set_len(sftp_tree, slen);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_SETSTAT (%d) id=%d [%s]", typ, id, path);
|
|
break;
|
|
}
|
|
// case SSH_FXP_FSETSTAT):{
|
|
// break;
|
|
// }
|
|
case SSH_FXP_OPENDIR:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_OPENDIR (%d) id=%d [%s]", typ, id, path);
|
|
break;
|
|
}
|
|
case SSH_FXP_READDIR:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_READDIR (%d) id=%d {%s}", typ, id, handle);
|
|
break;
|
|
}
|
|
case SSH_FXP_REMOVE:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_REMOVE (%d) id=%d [%s]", typ, id, path);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
break;
|
|
}
|
|
// case SSH_FXP_MKDIR:{
|
|
// break;
|
|
// }
|
|
// case SSH_FXP_RMDIR:{
|
|
// break;
|
|
// }
|
|
case SSH_FXP_REALPATH:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_REALPATH (%d) id=%d [%s]", typ, id, path);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
break;
|
|
}
|
|
case SSH_FXP_STAT:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * path = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s]", typ, id, path);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
break;
|
|
}
|
|
case SSH_FXP_RENAME:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * oldpath = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * newpath = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s] > [%s]", typ, id, oldpath, newpath);
|
|
break;
|
|
}
|
|
// case SSH_FXP_READLINK:{
|
|
// break;
|
|
// }
|
|
// case SSH_FXP_SYMLINK:{
|
|
// break;
|
|
// }
|
|
case SSH_FXP_STATUS:{
|
|
int id = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
int code = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_status, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint8 * err_msg = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, slen, ENC_UTF_8);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_lang_tag_length, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_lang_tag, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_STATUS (%d) id=%d code=%d [%s]", typ, id, code, err_msg);
|
|
break;
|
|
}
|
|
case SSH_FXP_HANDLE:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
gchar * handle = tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, slen);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA);
|
|
offset += slen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_HANDLE (%d) id=%d {%s}", typ, id, handle);
|
|
break;
|
|
}
|
|
case SSH_FXP_DATA:{
|
|
int id = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
int dlen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA);
|
|
offset += dlen;
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_DATA (%d) id=%d len=%d", typ, id, dlen);
|
|
break;
|
|
}
|
|
case SSH_FXP_NAME:{
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_NAME (%d)", typ);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint count = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_count, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
guint cnt;
|
|
for(cnt=0;cnt<count;cnt++){
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
slen = tvb_get_ntohl(tvb, offset) ;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln_len, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln, tvb, offset, slen, ENC_UTF_8);
|
|
offset += slen;
|
|
slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
|
|
offset += slen;
|
|
}
|
|
break;
|
|
}
|
|
case SSH_FXP_ATTRS:{
|
|
int id = tvb_get_ntohl(tvb, offset);
|
|
wmem_strbuf_append_printf(title, " SSH_FXP_ATTRS (%d) id=%d", typ, id);
|
|
proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree);
|
|
proto_item_set_len(sftp_tree, slen);
|
|
offset += slen;
|
|
break;
|
|
}
|
|
// case SSH_FXP_EXTENDED:{
|
|
// break;
|
|
// }
|
|
// case SSH_FXP_EXTENDED_REPLY:{
|
|
// break;
|
|
// }
|
|
default:{
|
|
wmem_strbuf_append_printf(title, " unknown (%d)", typ);
|
|
offset += plen;
|
|
break;
|
|
}
|
|
}
|
|
proto_item_set_text(sftp_tree, "%s", wmem_strbuf_get_str(title));
|
|
proto_item_set_len(sftp_tree, plen+4);
|
|
return offset;
|
|
}
|
|
|
|
static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo _U_,
|
|
int offset, proto_item *msg_type_tree)
|
|
{
|
|
wmem_strbuf_t *title = wmem_strbuf_new(wmem_packet_scope(), "SFTP attributes");
|
|
proto_item * sftp_attrs_tree = proto_tree_add_subtree(msg_type_tree, packet_tvb, offset, -1, ett_sftp_attrs, NULL, NULL);
|
|
|
|
int offset0 = offset;
|
|
guint flags = tvb_get_ntohl(packet_tvb, offset) ;
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_flags, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
if(flags & SSH_FILEXFER_ATTR_SIZE){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_size, packet_tvb, offset, 8, ENC_BIG_ENDIAN);
|
|
offset += 8;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_UIDGID){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_uid, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_UIDGID){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_gid, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_PERMISSIONS){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_permissions, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_ACMODTIME){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_atime, packet_tvb, offset, 4, ENC_TIME_SECS);
|
|
offset += 4;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_ACMODTIME){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_mtime, packet_tvb, offset, 4, ENC_TIME_SECS);
|
|
offset += 4;
|
|
}
|
|
if(flags & SSH_FILEXFER_ATTR_EXTENDED){
|
|
proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_extended_count, packet_tvb, offset, 4, ENC_BIG_ENDIAN);
|
|
offset += 4;
|
|
}
|
|
|
|
proto_item_set_text(sftp_attrs_tree, "%s", wmem_strbuf_get_str(title));
|
|
proto_item_set_len(sftp_attrs_tree, offset - offset0);
|
|
|
|
return offset - offset0;
|
|
}
|
|
|
|
void
|
|
proto_register_sftp(void)
|
|
{
|
|
static hf_register_info hf[] = {
|
|
{ &hf_ssh_sftp_len,
|
|
{ "SFTP packet length", "sftp.packet_length",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_type,
|
|
{ "SFTP packet type", "sftp.packet_type",
|
|
FT_UINT8, BASE_DEC, VALS(ssh2_sftp_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_version,
|
|
{ "SFTP version", "sftp.version",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_id,
|
|
{ "SFTP id", "sftp.id",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_path_len,
|
|
{ "SFTP path length", "sftp.path_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_path,
|
|
{ "SFTP path", "sftp.path",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_pflags,
|
|
{ "SFTP pflags", "sftp.pflags",
|
|
FT_UINT32, BASE_HEX, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_name_count,
|
|
{ "SFTP count", "sftp.name_count",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_name_fn_len,
|
|
{ "SFTP name file name length", "sftp.name_fn_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_name_fn,
|
|
{ "SFTP name file name", "sftp.name_fn",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_name_ln_len,
|
|
{ "SFTP name long name length", "sftp.name_ln_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_name_ln,
|
|
{ "SFTP name long name", "sftp.name_ln",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_flags,
|
|
{ "SFTP attributes flags", "sftp.attrs.flags",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_size,
|
|
{ "SFTP attributes file size", "sftp.attrs.size",
|
|
FT_UINT64, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_uid,
|
|
{ "SFTP attributes uid", "sftp.attrs.uid",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_gid,
|
|
{ "SFTP attributes gid", "sftp.attrs.gid",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_permissions,
|
|
{ "SFTP attributes permissions", "sftp.attrs.permissions",
|
|
FT_UINT32, BASE_OCT, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_atime,
|
|
{ "SFTP attributes access time", "sftp.attrs.atime",
|
|
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_mtime,
|
|
{ "SFTP attributes modification time", "sftp.attrs.mtime",
|
|
FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_attrs_extended_count,
|
|
{ "SFTP attributes extended count", "sftp.attrs.extended_count",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_offset,
|
|
{ "SFTP offset", "sftp.offset",
|
|
FT_UINT64, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_length,
|
|
{ "SFTP length", "sftp.length",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_handle_len,
|
|
{ "SFTP handle length", "sftp.handle_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_handle,
|
|
{ "SFTP handle", "sftp.handle",
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_status,
|
|
{ "SFTP error/status code", "sftp.status",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_error_message_len,
|
|
{ "SFTP error message length", "sftp.error_message_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_error_message,
|
|
{ "SFTP error message", "sftp.error_message",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_data_len,
|
|
{ "SFTP data length", "sftp.data_len",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_sftp_data,
|
|
{ "SFTP data", "sftp.data",
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_lang_tag_length,
|
|
{ "Language tag length", "sftp.lang_tag_length",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_ssh_lang_tag,
|
|
{ "Language tag", "sftp.lang_tag",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
&ett_sftp,
|
|
&ett_sftp_attrs,
|
|
};
|
|
|
|
proto_sftp = proto_register_protocol("SSH File Transfer Protocol", "SFTP", "sftp");
|
|
proto_register_field_array(proto_sftp, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
sftp_handle = register_dissector("sftp", dissect_sftp, proto_sftp);
|
|
}
|