diff options
author | Jerome-PS <jerome.hamm@planete-sciences.org> | 2022-01-18 13:09:06 +0000 |
---|---|---|
committer | A Wireshark GitLab Utility <6629907-ws-gitlab-utility@users.noreply.gitlab.com> | 2022-01-18 13:09:06 +0000 |
commit | 269e662442ec6262af7a60469774dff98a13c25d (patch) | |
tree | 3880c8d5f413c2cdd474efa9ba675d7b5a5c5a42 /epan/dissectors/packet-sftp.c | |
parent | ca61ee833ac886345ae5e6f4c239da7eae72f027 (diff) |
Adding dissection for subsystem sftp.
Diffstat (limited to 'epan/dissectors/packet-sftp.c')
-rw-r--r-- | epan/dissectors/packet-sftp.c | 705 |
1 files changed, 705 insertions, 0 deletions
diff --git a/epan/dissectors/packet-sftp.c b/epan/dissectors/packet-sftp.c new file mode 100644 index 0000000000..89e5da203e --- /dev/null +++ b/epan/dissectors/packet-sftp.c @@ -0,0 +1,705 @@ +/* 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 G_MESSAGES_DEBUG=sftp to see messages. */ +#define G_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, + 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)pinfo; +} + +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("SFTP 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); +} |