/src/wireshark/epan/dissectors/packet-sftp.c
Line | Count | Source |
1 | | /* packet-sftp.c |
2 | | * Routines for ssh packet dissection |
3 | | * |
4 | | * Jérôme Hamm |
5 | | * |
6 | | * Wireshark - Network traffic analyzer |
7 | | * By Gerald Combs <gerald@wireshark.org> |
8 | | * Copyright 1998 Gerald Combs |
9 | | * |
10 | | * Copied from packet-ssh.c |
11 | | * |
12 | | * SPDX-License-Identifier: GPL-2.0-or-later |
13 | | * |
14 | | * |
15 | | * Note: support for SFTP. |
16 | | * |
17 | | */ |
18 | | |
19 | | /* SFTP is defined in: |
20 | | * |
21 | | * draft-ietf-secsh-filexfer-02 - SSH File Transfer Protocol |
22 | | * |
23 | | */ |
24 | | |
25 | | #include "config.h" |
26 | | #define WS_LOG_DOMAIN "sftp" |
27 | | |
28 | | #include <epan/packet.h> |
29 | | #include <epan/expert.h> |
30 | | |
31 | | void proto_register_sftp(void); |
32 | | |
33 | | static int proto_sftp; |
34 | | |
35 | | static int hf_ssh_sftp_len; |
36 | | static int hf_ssh_sftp_type; |
37 | | static int hf_ssh_sftp_version; |
38 | | static int hf_ssh_sftp_id; |
39 | | static int hf_ssh_sftp_path_len; |
40 | | static int hf_ssh_sftp_path; |
41 | | static int hf_ssh_sftp_pflags; |
42 | | static int hf_ssh_sftp_name_count; |
43 | | static int hf_ssh_sftp_name_fn_len; |
44 | | static int hf_ssh_sftp_name_fn; |
45 | | static int hf_ssh_sftp_name_ln_len; |
46 | | static int hf_ssh_sftp_name_ln; |
47 | | static int hf_ssh_sftp_attrs_flags; |
48 | | static int hf_ssh_sftp_attrs_size; |
49 | | static int hf_ssh_sftp_attrs_uid; |
50 | | static int hf_ssh_sftp_attrs_gid; |
51 | | static int hf_ssh_sftp_attrs_permissions; |
52 | | static int hf_ssh_sftp_attrs_atime; |
53 | | static int hf_ssh_sftp_attrs_mtime; |
54 | | static int hf_ssh_sftp_attrs_extended_count; |
55 | | static int hf_ssh_sftp_handle_len; |
56 | | static int hf_ssh_sftp_handle; |
57 | | static int hf_ssh_sftp_status; |
58 | | static int hf_ssh_sftp_error_message_len; |
59 | | static int hf_ssh_sftp_error_message; |
60 | | static int hf_ssh_sftp_offset; |
61 | | static int hf_ssh_sftp_length; |
62 | | static int hf_ssh_sftp_data_len; |
63 | | static int hf_ssh_sftp_data; |
64 | | static int hf_ssh_lang_tag_length; |
65 | | static int hf_ssh_lang_tag; |
66 | | |
67 | | static int ett_sftp; |
68 | | static int ett_sftp_attrs; |
69 | | |
70 | | static dissector_handle_t sftp_handle; |
71 | | |
72 | 0 | #define SSH_FXP_INIT 1 |
73 | 0 | #define SSH_FXP_VERSION 2 |
74 | 0 | #define SSH_FXP_OPEN 3 |
75 | 0 | #define SSH_FXP_CLOSE 4 |
76 | 0 | #define SSH_FXP_READ 5 |
77 | 0 | #define SSH_FXP_WRITE 6 |
78 | 0 | #define SSH_FXP_LSTAT 7 |
79 | 0 | #define SSH_FXP_FSTAT 8 |
80 | 0 | #define SSH_FXP_SETSTAT 9 |
81 | | #define SSH_FXP_FSETSTAT 10 |
82 | 0 | #define SSH_FXP_OPENDIR 11 |
83 | 0 | #define SSH_FXP_READDIR 12 |
84 | 0 | #define SSH_FXP_REMOVE 13 |
85 | | #define SSH_FXP_MKDIR 14 |
86 | | #define SSH_FXP_RMDIR 15 |
87 | 0 | #define SSH_FXP_REALPATH 16 |
88 | 0 | #define SSH_FXP_STAT 17 |
89 | 0 | #define SSH_FXP_RENAME 18 |
90 | | #define SSH_FXP_READLINK 19 |
91 | | #define SSH_FXP_LINK 21 |
92 | | #define SSH_FXP_BLOCK 22 |
93 | | #define SSH_FXP_UNBLOCK 23 |
94 | | |
95 | 0 | #define SSH_FXP_STATUS 101 |
96 | 0 | #define SSH_FXP_HANDLE 102 |
97 | 0 | #define SSH_FXP_DATA 103 |
98 | 0 | #define SSH_FXP_NAME 104 |
99 | 0 | #define SSH_FXP_ATTRS 105 |
100 | | |
101 | | #define SSH_FXP_EXTENDED 200 |
102 | | #define SSH_FXP_EXTENDED_REPLY 201 |
103 | | |
104 | 0 | #define SSH_FILEXFER_ATTR_SIZE 0x00000001 |
105 | 0 | #define SSH_FILEXFER_ATTR_UIDGID 0x00000002 |
106 | 0 | #define SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004 |
107 | 0 | #define SSH_FILEXFER_ATTR_ACMODTIME 0x00000008 |
108 | 0 | #define SSH_FILEXFER_ATTR_EXTENDED 0x80000000 |
109 | | |
110 | | static const value_string ssh2_sftp_vals[] = { |
111 | | {SSH_FXP_INIT, "SSH_FXP_INIT"}, |
112 | | {SSH_FXP_VERSION, "SSH_FXP_VERSION"}, |
113 | | {SSH_FXP_OPEN, "SSH_FXP_OPEN"}, |
114 | | {SSH_FXP_CLOSE, "SSH_FXP_CLOSE"}, |
115 | | {SSH_FXP_READ, "SSH_FXP_READ"}, |
116 | | {SSH_FXP_WRITE, "SSH_FXP_WRITE"}, |
117 | | {SSH_FXP_LSTAT, "SSH_FXP_LSTAT"}, |
118 | | {SSH_FXP_FSTAT, "SSH_FXP_FSTAT"}, |
119 | | {SSH_FXP_SETSTAT, "SSH_FXP_SETSTAT"}, |
120 | | {SSH_FXP_FSETSTAT, "SSH_FXP_FSETSTAT"}, |
121 | | {SSH_FXP_OPENDIR, "SSH_FXP_OPENDIR"}, |
122 | | {SSH_FXP_READDIR, "SSH_FXP_READDIR"}, |
123 | | {SSH_FXP_REMOVE, "SSH_FXP_REMOVE"}, |
124 | | {SSH_FXP_MKDIR, "SSH_FXP_MKDIR"}, |
125 | | {SSH_FXP_RMDIR, "SSH_FXP_RMDIR"}, |
126 | | {SSH_FXP_REALPATH, "SSH_FXP_REALPATH"}, |
127 | | {SSH_FXP_STAT, "SSH_FXP_STAT"}, |
128 | | {SSH_FXP_RENAME, "SSH_FXP_RENAME"}, |
129 | | {SSH_FXP_READLINK, "SSH_FXP_READLINK"}, |
130 | | {SSH_FXP_LINK, "SSH_FXP_LINK"}, |
131 | | {SSH_FXP_BLOCK, "SSH_FXP_BLOCK"}, |
132 | | {SSH_FXP_UNBLOCK, "SSH_FXP_UNBLOCK"}, |
133 | | {SSH_FXP_STATUS, "SSH_FXP_STATUS"}, |
134 | | {SSH_FXP_HANDLE, "SSH_FXP_HANDLE"}, |
135 | | {SSH_FXP_DATA, "SSH_FXP_DATA"}, |
136 | | {SSH_FXP_NAME, "SSH_FXP_NAME"}, |
137 | | {SSH_FXP_ATTRS, "SSH_FXP_ATTRS"}, |
138 | | {SSH_FXP_EXTENDED, "SSH_FXP_EXTENDED"}, |
139 | | {SSH_FXP_EXTENDED_REPLY, "SSH_FXP_EXTENDED_REPLY"}, |
140 | | {0, NULL} |
141 | | }; |
142 | | |
143 | | static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_); |
144 | | static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo, |
145 | | int offset, proto_item *msg_type_tree); |
146 | | |
147 | | static int dissect_sftp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
148 | 0 | { |
149 | 0 | unsigned offset = 0; |
150 | 0 | unsigned plen; |
151 | 0 | unsigned slen; |
152 | 0 | if (pinfo->can_desegment) { |
153 | 0 | if (tvb_captured_length_remaining(tvb, offset) < 4) { |
154 | 0 | pinfo->desegment_offset = offset; |
155 | 0 | pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; |
156 | 0 | return tvb_captured_length(tvb); |
157 | 0 | } |
158 | 0 | } |
159 | | |
160 | 0 | plen = tvb_get_ntohl(tvb, offset); |
161 | 0 | if (pinfo->can_desegment) { |
162 | 0 | unsigned length_remaining = tvb_captured_length_remaining(tvb, offset + 4); |
163 | 0 | if (length_remaining < plen) { |
164 | 0 | pinfo->desegment_offset = offset; |
165 | 0 | pinfo->desegment_len = plen - length_remaining; |
166 | 0 | return tvb_captured_length(tvb); |
167 | 0 | } |
168 | 0 | } |
169 | | |
170 | 0 | wmem_strbuf_t *title = wmem_strbuf_new(pinfo->pool, ""); |
171 | 0 | proto_item *ti = proto_tree_add_item(tree, proto_sftp, tvb, offset, -1, ENC_NA); |
172 | 0 | proto_tree *sftp_tree = proto_item_add_subtree(ti, ett_sftp); |
173 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
174 | 0 | offset += 4; |
175 | 0 | uint8_t typ; |
176 | 0 | typ = tvb_get_uint8(tvb, offset) ; |
177 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_type, tvb, offset, 1, ENC_BIG_ENDIAN); |
178 | 0 | offset += 1; |
179 | 0 | col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(pinfo->pool, typ, ssh2_sftp_vals, "Unknown (%u)")); |
180 | 0 | switch(typ){ |
181 | 0 | case SSH_FXP_INIT:{ |
182 | 0 | int ver = tvb_get_ntohl(tvb, offset) ; |
183 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_INIT (%d) version %d", typ, ver); |
184 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN); |
185 | 0 | offset += 4; |
186 | 0 | break; |
187 | 0 | } |
188 | 0 | case SSH_FXP_VERSION:{ |
189 | 0 | int ver = tvb_get_ntohl(tvb, offset) ; |
190 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_VERSION (%d) version %d", typ, ver); |
191 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_version, tvb, offset, 4, ENC_BIG_ENDIAN); |
192 | 0 | offset += 4; |
193 | 0 | break; |
194 | 0 | } |
195 | 0 | case SSH_FXP_OPEN:{ |
196 | 0 | int id = tvb_get_ntohl(tvb, offset) ; |
197 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
198 | 0 | offset += 4; |
199 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
200 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
201 | 0 | offset += 4; |
202 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
203 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
204 | 0 | offset += slen; |
205 | | // int pflags = tvb_get_ntohl(tvb, offset) ; |
206 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_pflags, tvb, offset, 4, ENC_BIG_ENDIAN); |
207 | 0 | offset += 4; |
208 | 0 | slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree); |
209 | 0 | offset += slen; |
210 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_OPEN (%d) id=%d [%s]", typ, id, path); |
211 | 0 | break; |
212 | 0 | } |
213 | 0 | case SSH_FXP_CLOSE:{ |
214 | 0 | int id = tvb_get_ntohl(tvb, offset) ; |
215 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
216 | 0 | offset += 4; |
217 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
218 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
219 | 0 | offset += 4; |
220 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
221 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
222 | 0 | offset += slen; |
223 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_CLOSE (%d) id=%d {%s}", typ, id, handle); |
224 | 0 | break; |
225 | 0 | } |
226 | 0 | case SSH_FXP_READ:{ |
227 | 0 | int id = tvb_get_ntohl(tvb, offset) ; |
228 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
229 | 0 | offset += 4; |
230 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
231 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
232 | 0 | offset += 4; |
233 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
234 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
235 | 0 | offset += slen; |
236 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN); |
237 | 0 | offset += 8; |
238 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_length, tvb, offset, 4, ENC_BIG_ENDIAN); |
239 | 0 | offset += 4; |
240 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_READ (%d) id=%d {%s}", typ, id, handle); |
241 | 0 | break; |
242 | 0 | } |
243 | 0 | case SSH_FXP_WRITE:{ |
244 | 0 | int id = tvb_get_ntohl(tvb, offset); |
245 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
246 | 0 | offset += 4; |
247 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
248 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
249 | 0 | offset += 4; |
250 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
251 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
252 | 0 | offset += slen; |
253 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_offset, tvb, offset, 8, ENC_BIG_ENDIAN); |
254 | 0 | offset += 8; |
255 | 0 | int dlen = tvb_get_ntohl(tvb, offset); |
256 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
257 | 0 | offset += 4; |
258 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA); |
259 | 0 | offset += dlen; |
260 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_WRITE (%d) id=%d {%s} len=%d", typ, id, handle, dlen); |
261 | 0 | break; |
262 | 0 | } |
263 | 0 | case SSH_FXP_LSTAT:{ |
264 | 0 | int id = tvb_get_ntohl(tvb, offset); |
265 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
266 | 0 | offset += 4; |
267 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
268 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
269 | 0 | offset += 4; |
270 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
271 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_LSTAT (%d) id=%d [%s]", typ, id, path); |
272 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
273 | 0 | offset += slen; |
274 | 0 | break; |
275 | 0 | } |
276 | 0 | case SSH_FXP_FSTAT:{ |
277 | 0 | int id = tvb_get_ntohl(tvb, offset); |
278 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
279 | 0 | offset += 4; |
280 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
281 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
282 | 0 | offset += 4; |
283 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
284 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
285 | 0 | offset += slen; |
286 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_FSTAT (%d) id=%d {%s}", typ, id, handle); |
287 | 0 | break; |
288 | 0 | } |
289 | 0 | case SSH_FXP_SETSTAT:{ |
290 | 0 | int id = tvb_get_ntohl(tvb, offset); |
291 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
292 | 0 | offset += 4; |
293 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
294 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
295 | 0 | offset += 4; |
296 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
297 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
298 | 0 | offset += slen; |
299 | 0 | slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree); |
300 | 0 | proto_item_set_len(sftp_tree, slen); |
301 | 0 | offset += slen; |
302 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_SETSTAT (%d) id=%d [%s]", typ, id, path); |
303 | 0 | break; |
304 | 0 | } |
305 | | // case SSH_FXP_FSETSTAT):{ |
306 | | // break; |
307 | | // } |
308 | 0 | case SSH_FXP_OPENDIR:{ |
309 | 0 | int id = tvb_get_ntohl(tvb, offset); |
310 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
311 | 0 | offset += 4; |
312 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
313 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
314 | 0 | offset += 4; |
315 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
316 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
317 | 0 | offset += slen; |
318 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_OPENDIR (%d) id=%d [%s]", typ, id, path); |
319 | 0 | break; |
320 | 0 | } |
321 | 0 | case SSH_FXP_READDIR:{ |
322 | 0 | int id = tvb_get_ntohl(tvb, offset); |
323 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
324 | 0 | offset += 4; |
325 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
326 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
327 | 0 | offset += 4; |
328 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
329 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
330 | 0 | offset += slen; |
331 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_READDIR (%d) id=%d {%s}", typ, id, handle); |
332 | 0 | break; |
333 | 0 | } |
334 | 0 | case SSH_FXP_REMOVE:{ |
335 | 0 | int id = tvb_get_ntohl(tvb, offset); |
336 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
337 | 0 | offset += 4; |
338 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
339 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
340 | 0 | offset += 4; |
341 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
342 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_REMOVE (%d) id=%d [%s]", typ, id, path); |
343 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
344 | 0 | offset += slen; |
345 | 0 | break; |
346 | 0 | } |
347 | | // case SSH_FXP_MKDIR:{ |
348 | | // break; |
349 | | // } |
350 | | // case SSH_FXP_RMDIR:{ |
351 | | // break; |
352 | | // } |
353 | 0 | case SSH_FXP_REALPATH:{ |
354 | 0 | int id = tvb_get_ntohl(tvb, offset); |
355 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
356 | 0 | offset += 4; |
357 | 0 | slen = tvb_get_ntohl(tvb, offset); |
358 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
359 | 0 | offset += 4; |
360 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
361 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_REALPATH (%d) id=%d [%s]", typ, id, path); |
362 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
363 | 0 | offset += slen; |
364 | 0 | break; |
365 | 0 | } |
366 | 0 | case SSH_FXP_STAT:{ |
367 | 0 | int id = tvb_get_ntohl(tvb, offset); |
368 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
369 | 0 | offset += 4; |
370 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
371 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
372 | 0 | offset += 4; |
373 | 0 | uint8_t * path = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
374 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s]", typ, id, path); |
375 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
376 | 0 | offset += slen; |
377 | 0 | break; |
378 | 0 | } |
379 | 0 | case SSH_FXP_RENAME:{ |
380 | 0 | int id = tvb_get_ntohl(tvb, offset); |
381 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
382 | 0 | offset += 4; |
383 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
384 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
385 | 0 | offset += 4; |
386 | 0 | uint8_t * oldpath = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
387 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
388 | 0 | offset += slen; |
389 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
390 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
391 | 0 | offset += 4; |
392 | 0 | uint8_t * newpath = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
393 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_path, tvb, offset, slen, ENC_UTF_8); |
394 | 0 | offset += slen; |
395 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_STAT (%d) id=%d [%s] > [%s]", typ, id, oldpath, newpath); |
396 | 0 | break; |
397 | 0 | } |
398 | | // case SSH_FXP_READLINK:{ |
399 | | // break; |
400 | | // } |
401 | | // case SSH_FXP_SYMLINK:{ |
402 | | // break; |
403 | | // } |
404 | 0 | case SSH_FXP_STATUS:{ |
405 | 0 | int id = tvb_get_ntohl(tvb, offset) ; |
406 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
407 | 0 | offset += 4; |
408 | 0 | int code = tvb_get_ntohl(tvb, offset) ; |
409 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_status, tvb, offset, 4, ENC_BIG_ENDIAN); |
410 | 0 | offset += 4; |
411 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
412 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
413 | 0 | offset += 4; |
414 | 0 | uint8_t * err_msg = tvb_get_string_enc(pinfo->pool, tvb, offset, slen, ENC_UTF_8); |
415 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_error_message, tvb, offset, slen, ENC_UTF_8); |
416 | 0 | offset += slen; |
417 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
418 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_lang_tag_length, tvb, offset, 4, ENC_BIG_ENDIAN); |
419 | 0 | offset += 4; |
420 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_lang_tag, tvb, offset, slen, ENC_UTF_8); |
421 | 0 | offset += slen; |
422 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_STATUS (%d) id=%d code=%d [%s]", typ, id, code, err_msg); |
423 | 0 | break; |
424 | 0 | } |
425 | 0 | case SSH_FXP_HANDLE:{ |
426 | 0 | int id = tvb_get_ntohl(tvb, offset); |
427 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
428 | 0 | offset += 4; |
429 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
430 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
431 | 0 | offset += 4; |
432 | 0 | char * handle = tvb_bytes_to_str(pinfo->pool, tvb, offset, slen); |
433 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_handle, tvb, offset, slen, ENC_NA); |
434 | 0 | offset += slen; |
435 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_HANDLE (%d) id=%d {%s}", typ, id, handle); |
436 | 0 | break; |
437 | 0 | } |
438 | 0 | case SSH_FXP_DATA:{ |
439 | 0 | int id = tvb_get_ntohl(tvb, offset) ; |
440 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
441 | 0 | offset += 4; |
442 | 0 | int dlen = tvb_get_ntohl(tvb, offset) ; |
443 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_data_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
444 | 0 | offset += 4; |
445 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_data, tvb, offset, dlen, ENC_NA); |
446 | 0 | offset += dlen; |
447 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_DATA (%d) id=%d len=%d", typ, id, dlen); |
448 | 0 | break; |
449 | 0 | } |
450 | 0 | case SSH_FXP_NAME:{ |
451 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_NAME (%d)", typ); |
452 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
453 | 0 | offset += 4; |
454 | 0 | unsigned count = tvb_get_ntohl(tvb, offset) ; |
455 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_count, tvb, offset, 4, ENC_BIG_ENDIAN); |
456 | 0 | offset += 4; |
457 | 0 | unsigned cnt; |
458 | 0 | for(cnt=0;cnt<count;cnt++){ |
459 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
460 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
461 | 0 | offset += 4; |
462 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_fn, tvb, offset, slen, ENC_UTF_8); |
463 | 0 | offset += slen; |
464 | 0 | slen = tvb_get_ntohl(tvb, offset) ; |
465 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln_len, tvb, offset, 4, ENC_BIG_ENDIAN); |
466 | 0 | offset += 4; |
467 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_name_ln, tvb, offset, slen, ENC_UTF_8); |
468 | 0 | offset += slen; |
469 | 0 | slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree); |
470 | 0 | offset += slen; |
471 | 0 | } |
472 | 0 | break; |
473 | 0 | } |
474 | 0 | case SSH_FXP_ATTRS:{ |
475 | 0 | int id = tvb_get_ntohl(tvb, offset); |
476 | 0 | wmem_strbuf_append_printf(title, " SSH_FXP_ATTRS (%d) id=%d", typ, id); |
477 | 0 | proto_tree_add_item(sftp_tree, hf_ssh_sftp_id, tvb, offset, 4, ENC_BIG_ENDIAN); |
478 | 0 | offset += 4; |
479 | 0 | slen = dissect_sftp_attrs(tvb, pinfo, offset, sftp_tree); |
480 | 0 | proto_item_set_len(sftp_tree, slen); |
481 | 0 | offset += slen; |
482 | 0 | break; |
483 | 0 | } |
484 | | // case SSH_FXP_EXTENDED:{ |
485 | | // break; |
486 | | // } |
487 | | // case SSH_FXP_EXTENDED_REPLY:{ |
488 | | // break; |
489 | | // } |
490 | 0 | default:{ |
491 | 0 | wmem_strbuf_append_printf(title, " unknown (%d)", typ); |
492 | 0 | offset += plen; |
493 | 0 | break; |
494 | 0 | } |
495 | 0 | } |
496 | 0 | proto_item_append_text(ti, ",%s", wmem_strbuf_get_str(title)); |
497 | 0 | proto_item_set_len(sftp_tree, plen+4); |
498 | 0 | return offset; |
499 | 0 | } |
500 | | |
501 | | static int dissect_sftp_attrs(tvbuff_t *packet_tvb, packet_info *pinfo, |
502 | | int offset, proto_item *msg_type_tree) |
503 | 0 | { |
504 | 0 | wmem_strbuf_t *title = wmem_strbuf_new(pinfo->pool, "SFTP attributes"); |
505 | 0 | proto_item * sftp_attrs_tree = proto_tree_add_subtree(msg_type_tree, packet_tvb, offset, -1, ett_sftp_attrs, NULL, NULL); |
506 | |
|
507 | 0 | int offset0 = offset; |
508 | 0 | unsigned flags = tvb_get_ntohl(packet_tvb, offset) ; |
509 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_flags, packet_tvb, offset, 4, ENC_BIG_ENDIAN); |
510 | 0 | offset += 4; |
511 | 0 | if(flags & SSH_FILEXFER_ATTR_SIZE){ |
512 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_size, packet_tvb, offset, 8, ENC_BIG_ENDIAN); |
513 | 0 | offset += 8; |
514 | 0 | } |
515 | 0 | if(flags & SSH_FILEXFER_ATTR_UIDGID){ |
516 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_uid, packet_tvb, offset, 4, ENC_BIG_ENDIAN); |
517 | 0 | offset += 4; |
518 | 0 | } |
519 | 0 | if(flags & SSH_FILEXFER_ATTR_UIDGID){ |
520 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_gid, packet_tvb, offset, 4, ENC_BIG_ENDIAN); |
521 | 0 | offset += 4; |
522 | 0 | } |
523 | 0 | if(flags & SSH_FILEXFER_ATTR_PERMISSIONS){ |
524 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_permissions, packet_tvb, offset, 4, ENC_BIG_ENDIAN); |
525 | 0 | offset += 4; |
526 | 0 | } |
527 | 0 | if(flags & SSH_FILEXFER_ATTR_ACMODTIME){ |
528 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_atime, packet_tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN); |
529 | 0 | offset += 4; |
530 | 0 | } |
531 | 0 | if(flags & SSH_FILEXFER_ATTR_ACMODTIME){ |
532 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_mtime, packet_tvb, offset, 4, ENC_TIME_SECS|ENC_BIG_ENDIAN); |
533 | 0 | offset += 4; |
534 | 0 | } |
535 | 0 | if(flags & SSH_FILEXFER_ATTR_EXTENDED){ |
536 | 0 | proto_tree_add_item(sftp_attrs_tree, hf_ssh_sftp_attrs_extended_count, packet_tvb, offset, 4, ENC_BIG_ENDIAN); |
537 | 0 | offset += 4; |
538 | 0 | } |
539 | |
|
540 | 0 | proto_item_set_text(sftp_attrs_tree, "%s", wmem_strbuf_get_str(title)); |
541 | 0 | proto_item_set_len(sftp_attrs_tree, offset - offset0); |
542 | |
|
543 | 0 | return offset - offset0; |
544 | 0 | } |
545 | | |
546 | | void |
547 | | proto_register_sftp(void) |
548 | 16 | { |
549 | 16 | static hf_register_info hf[] = { |
550 | 16 | { &hf_ssh_sftp_len, |
551 | 16 | { "SFTP packet length", "sftp.packet_length", |
552 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
553 | 16 | NULL, HFILL }}, |
554 | | |
555 | 16 | { &hf_ssh_sftp_type, |
556 | 16 | { "SFTP packet type", "sftp.packet_type", |
557 | 16 | FT_UINT8, BASE_DEC, VALS(ssh2_sftp_vals), 0x0, |
558 | 16 | NULL, HFILL }}, |
559 | | |
560 | 16 | { &hf_ssh_sftp_version, |
561 | 16 | { "SFTP version", "sftp.version", |
562 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
563 | 16 | NULL, HFILL }}, |
564 | | |
565 | 16 | { &hf_ssh_sftp_id, |
566 | 16 | { "SFTP id", "sftp.id", |
567 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
568 | 16 | NULL, HFILL }}, |
569 | | |
570 | 16 | { &hf_ssh_sftp_path_len, |
571 | 16 | { "SFTP path length", "sftp.path_len", |
572 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
573 | 16 | NULL, HFILL }}, |
574 | | |
575 | 16 | { &hf_ssh_sftp_path, |
576 | 16 | { "SFTP path", "sftp.path", |
577 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
578 | 16 | NULL, HFILL }}, |
579 | | |
580 | 16 | { &hf_ssh_sftp_pflags, |
581 | 16 | { "SFTP pflags", "sftp.pflags", |
582 | 16 | FT_UINT32, BASE_HEX, NULL, 0x0, |
583 | 16 | NULL, HFILL }}, |
584 | | |
585 | 16 | { &hf_ssh_sftp_name_count, |
586 | 16 | { "SFTP count", "sftp.name_count", |
587 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
588 | 16 | NULL, HFILL }}, |
589 | | |
590 | 16 | { &hf_ssh_sftp_name_fn_len, |
591 | 16 | { "SFTP name file name length", "sftp.name_fn_len", |
592 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
593 | 16 | NULL, HFILL }}, |
594 | | |
595 | 16 | { &hf_ssh_sftp_name_fn, |
596 | 16 | { "SFTP name file name", "sftp.name_fn", |
597 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
598 | 16 | NULL, HFILL }}, |
599 | | |
600 | 16 | { &hf_ssh_sftp_name_ln_len, |
601 | 16 | { "SFTP name long name length", "sftp.name_ln_len", |
602 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
603 | 16 | NULL, HFILL }}, |
604 | | |
605 | 16 | { &hf_ssh_sftp_name_ln, |
606 | 16 | { "SFTP name long name", "sftp.name_ln", |
607 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
608 | 16 | NULL, HFILL }}, |
609 | | |
610 | 16 | { &hf_ssh_sftp_attrs_flags, |
611 | 16 | { "SFTP attributes flags", "sftp.attrs.flags", |
612 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
613 | 16 | NULL, HFILL }}, |
614 | | |
615 | 16 | { &hf_ssh_sftp_attrs_size, |
616 | 16 | { "SFTP attributes file size", "sftp.attrs.size", |
617 | 16 | FT_UINT64, BASE_DEC, NULL, 0x0, |
618 | 16 | NULL, HFILL }}, |
619 | | |
620 | 16 | { &hf_ssh_sftp_attrs_uid, |
621 | 16 | { "SFTP attributes uid", "sftp.attrs.uid", |
622 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
623 | 16 | NULL, HFILL }}, |
624 | | |
625 | 16 | { &hf_ssh_sftp_attrs_gid, |
626 | 16 | { "SFTP attributes gid", "sftp.attrs.gid", |
627 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
628 | 16 | NULL, HFILL }}, |
629 | | |
630 | 16 | { &hf_ssh_sftp_attrs_permissions, |
631 | 16 | { "SFTP attributes permissions", "sftp.attrs.permissions", |
632 | 16 | FT_UINT32, BASE_OCT, NULL, 0x0, |
633 | 16 | NULL, HFILL }}, |
634 | | |
635 | 16 | { &hf_ssh_sftp_attrs_atime, |
636 | 16 | { "SFTP attributes access time", "sftp.attrs.atime", |
637 | 16 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, |
638 | 16 | NULL, HFILL }}, |
639 | | |
640 | 16 | { &hf_ssh_sftp_attrs_mtime, |
641 | 16 | { "SFTP attributes modification time", "sftp.attrs.mtime", |
642 | 16 | FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, |
643 | 16 | NULL, HFILL }}, |
644 | | |
645 | 16 | { &hf_ssh_sftp_attrs_extended_count, |
646 | 16 | { "SFTP attributes extended count", "sftp.attrs.extended_count", |
647 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
648 | 16 | NULL, HFILL }}, |
649 | | |
650 | 16 | { &hf_ssh_sftp_offset, |
651 | 16 | { "SFTP offset", "sftp.offset", |
652 | 16 | FT_UINT64, BASE_DEC, NULL, 0x0, |
653 | 16 | NULL, HFILL }}, |
654 | | |
655 | 16 | { &hf_ssh_sftp_length, |
656 | 16 | { "SFTP length", "sftp.length", |
657 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
658 | 16 | NULL, HFILL }}, |
659 | | |
660 | 16 | { &hf_ssh_sftp_handle_len, |
661 | 16 | { "SFTP handle length", "sftp.handle_len", |
662 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
663 | 16 | NULL, HFILL }}, |
664 | | |
665 | 16 | { &hf_ssh_sftp_handle, |
666 | 16 | { "SFTP handle", "sftp.handle", |
667 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
668 | 16 | NULL, HFILL }}, |
669 | | |
670 | 16 | { &hf_ssh_sftp_status, |
671 | 16 | { "SFTP error/status code", "sftp.status", |
672 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
673 | 16 | NULL, HFILL }}, |
674 | | |
675 | 16 | { &hf_ssh_sftp_error_message_len, |
676 | 16 | { "SFTP error message length", "sftp.error_message_len", |
677 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
678 | 16 | NULL, HFILL }}, |
679 | | |
680 | 16 | { &hf_ssh_sftp_error_message, |
681 | 16 | { "SFTP error message", "sftp.error_message", |
682 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
683 | 16 | NULL, HFILL }}, |
684 | | |
685 | 16 | { &hf_ssh_sftp_data_len, |
686 | 16 | { "SFTP data length", "sftp.data_len", |
687 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
688 | 16 | NULL, HFILL }}, |
689 | | |
690 | 16 | { &hf_ssh_sftp_data, |
691 | 16 | { "SFTP data", "sftp.data", |
692 | 16 | FT_BYTES, BASE_NONE, NULL, 0x0, |
693 | 16 | NULL, HFILL }}, |
694 | | |
695 | 16 | { &hf_ssh_lang_tag_length, |
696 | 16 | { "Language tag length", "sftp.lang_tag_length", |
697 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, |
698 | 16 | NULL, HFILL }}, |
699 | | |
700 | 16 | { &hf_ssh_lang_tag, |
701 | 16 | { "Language tag", "sftp.lang_tag", |
702 | 16 | FT_STRING, BASE_NONE, NULL, 0x0, |
703 | 16 | NULL, HFILL }}, |
704 | | |
705 | 16 | }; |
706 | | |
707 | 16 | static int *ett[] = { |
708 | 16 | &ett_sftp, |
709 | 16 | &ett_sftp_attrs, |
710 | 16 | }; |
711 | | |
712 | 16 | proto_sftp = proto_register_protocol("SSH File Transfer Protocol", "SFTP", "sftp"); |
713 | 16 | proto_register_field_array(proto_sftp, hf, array_length(hf)); |
714 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
715 | | |
716 | 16 | sftp_handle = register_dissector("sftp", dissect_sftp, proto_sftp); |
717 | 16 | } |