Fixup: tvb_get_string(z) -> tvb_get_string(z)_enc
[metze/wireshark/wip.git] / epan / dissectors / packet-ssh.c
1 /* packet-ssh.c
2  * Routines for ssh packet dissection
3  *
4  * Huagang XIE <huagang@intruvert.com>
5  * Kees Cook <kees@outflux.net>
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from packet-mysql.c
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  *
27  *
28  * Note:  support SSH v1 and v2  now.
29  *
30  */
31
32 /* SSH version 2 is defined in:
33  *
34  * RFC 4250: The Secure Shell (SSH) Protocol Assigned Numbers
35  * RFC 4251: The Secure Shell (SSH) Protocol Architecture
36  * RFC 4252: The Secure Shell (SSH) Authentication Protocol
37  * RFC 4253: The Secure Shell (SSH) Transport Layer Protocol
38  * RFC 4254: The Secure Shell (SSH) Connection Protocol
39  *
40  * SSH versions under 2 were never officially standardized.
41  *
42  * Diffie-Hellman Group Exchange is defined in:
43  *
44  * RFC 4419: Diffie-Hellman Group Exchange for
45  *   the Secure Shell (SSH) Transport Layer Protocol
46  */
47
48 /* "SSH" prefixes are for version 2, whereas "SSH1" is for version 1 */
49
50 #include "config.h"
51
52 #include <glib.h>
53
54 #include <epan/packet.h>
55 #include <epan/exceptions.h>
56 #include <epan/conversation.h>
57 #include <epan/wmem/wmem.h>
58 #include <epan/sctpppids.h>
59 #include <epan/prefs.h>
60 #include <epan/expert.h>
61
62 #include "packet-tcp.h"
63
64 void proto_register_ssh(void);
65 void proto_reg_handoff_ssh(void);
66
67 /* SSH Version 1 definition , from openssh ssh1.h */
68 #define SSH1_MSG_NONE                   0       /* no message */
69 #define SSH1_MSG_DISCONNECT             1       /* cause (string) */
70 #define SSH1_SMSG_PUBLIC_KEY            2       /* ck,msk,srvk,hostk */
71 #define SSH1_CMSG_SESSION_KEY           3       /* key (BIGNUM) */
72 #define SSH1_CMSG_USER                  4       /* user (string) */
73
74
75 #define SSH_VERSION_UNKNOWN     0
76 #define SSH_VERSION_1           1
77 #define SSH_VERSION_2           2
78
79 /* proto data */
80
81 struct ssh_peer_data {
82         guint   counter;
83
84         guint32 frame_version_start;
85         guint32 frame_version_end;
86
87         guint32 frame_key_start;
88         guint32 frame_key_end;
89
90         gchar*  kex_proposal;
91
92         /* For all subsequent proposals,
93            [0] is client-to-server and [1] is server-to-client. */
94 #define CLIENT_TO_SERVER_PROPOSAL 0
95 #define SERVER_TO_CLIENT_PROPOSAL 1
96
97         gchar*  mac_proposals[2];
98         gchar*  mac;
99         gint    mac_length;
100
101         gchar*  enc_proposals[2];
102         gchar*  enc;
103
104         gchar*  comp_proposals[2];
105         gchar*  comp;
106
107         gint    length_is_plaintext;
108 };
109
110 struct ssh_flow_data {
111         guint   version;
112
113         gchar*  kex;
114         int   (*kex_specific_dissector)(guint8 msg_code, tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree);
115
116         /* [0] is client's, [1] is server's */
117 #define CLIENT_PEER_DATA 0
118 #define SERVER_PEER_DATA 1
119         struct ssh_peer_data peer_data[2];
120 };
121
122 static int proto_ssh = -1;
123 static int hf_ssh_packet_length= -1;
124 static int hf_ssh_packet_length_encrypted= -1;
125 static int hf_ssh_padding_length= -1;
126 static int hf_ssh_payload= -1;
127 static int hf_ssh_protocol= -1;
128 static int hf_ssh_dh_gex_min= -1;
129 static int hf_ssh_dh_gex_nbits= -1;
130 static int hf_ssh_dh_gex_max= -1;
131 static int hf_ssh_encrypted_packet= -1;
132 static int hf_ssh_padding_string= -1;
133 static int hf_ssh_mac_string= -1;
134 static int hf_ssh_msg_code = -1;
135 static int hf_ssh2_msg_code = -1;
136 static int hf_ssh2_kex_dh_msg_code = -1;
137 static int hf_ssh2_kex_dh_gex_msg_code = -1;
138 static int hf_ssh_cookie = -1;
139 static int hf_ssh_mpint_g= -1;
140 static int hf_ssh_mpint_p= -1;
141 static int hf_ssh_mpint_e= -1;
142 static int hf_ssh_mpint_f= -1;
143 static int hf_ssh_mpint_length= -1;
144 static int hf_ssh_kexdh_host_key= -1;
145 static int hf_ssh_kexdh_host_key_length= -1;
146 static int hf_ssh_kexdh_h_sig= -1;
147 static int hf_ssh_kexdh_h_sig_length= -1;
148 static int hf_ssh_kex_algorithms = -1;
149 static int hf_ssh_server_host_key_algorithms = -1;
150 static int hf_ssh_encryption_algorithms_client_to_server = -1;
151 static int hf_ssh_encryption_algorithms_server_to_client = -1;
152 static int hf_ssh_mac_algorithms_client_to_server=-1;
153 static int hf_ssh_mac_algorithms_server_to_client=-1;
154 static int hf_ssh_compression_algorithms_client_to_server=-1;
155 static int hf_ssh_compression_algorithms_server_to_client=-1;
156 static int hf_ssh_languages_client_to_server=-1;
157 static int hf_ssh_languages_server_to_client=-1;
158 static int hf_ssh_kex_algorithms_length= -1;
159 static int hf_ssh_server_host_key_algorithms_length= -1;
160 static int hf_ssh_encryption_algorithms_client_to_server_length= -1;
161 static int hf_ssh_encryption_algorithms_server_to_client_length= -1;
162 static int hf_ssh_mac_algorithms_client_to_server_length= -1;
163 static int hf_ssh_mac_algorithms_server_to_client_length= -1;
164 static int hf_ssh_compression_algorithms_client_to_server_length= -1;
165 static int hf_ssh_compression_algorithms_server_to_client_length= -1;
166 static int hf_ssh_languages_client_to_server_length= -1;
167 static int hf_ssh_languages_server_to_client_length= -1;
168 static int hf_ssh_kex_first_packet_follows = -1;
169 static int hf_ssh_kex_reserved = -1;
170
171 static gint ett_ssh = -1;
172 static gint ett_key_exchange = -1;
173 static gint ett_key_init = -1;
174 static gint ett_ssh1 = -1;
175 static gint ett_ssh2 = -1;
176
177 static expert_field ei_ssh_packet_length = EI_INIT;
178
179 static gboolean ssh_desegment = TRUE;
180
181 static dissector_handle_t ssh_handle;
182
183 #define TCP_PORT_SSH  22
184 #define SCTP_PORT_SSH 22
185
186 /* Message Numbers (from RFC 4250) (1-255) */
187
188 /* Transport layer protocol: generic (1-19) */
189 #define SSH_MSG_DISCONNECT                      1
190 #define SSH_MSG_IGNORE                          2
191 #define SSH_MSG_UNIMPLEMENTED           3
192 #define SSH_MSG_DEBUG                           4
193 #define SSH_MSG_SERVICE_REQUEST         5
194 #define SSH_MSG_SERVICE_ACCEPT          6
195
196 /* Transport layer protocol: Algorithm negotiation (20-29) */
197 #define SSH_MSG_KEXINIT                         20
198 #define SSH_MSG_NEWKEYS                         21
199
200 /* Transport layer: Key exchange method specific (reusable) (30-49) */
201 #define SSH_MSG_KEXDH_INIT                      30
202 #define SSH_MSG_KEXDH_REPLY                     31
203
204 #define SSH_MSG_KEX_DH_GEX_REQUEST_OLD  30
205 #define SSH_MSG_KEX_DH_GEX_GROUP                31
206 #define SSH_MSG_KEX_DH_GEX_INIT                 32
207 #define SSH_MSG_KEX_DH_GEX_REPLY                33
208 #define SSH_MSG_KEX_DH_GEX_REQUEST              34
209
210 /* User authentication protocol: generic (50-59) */
211 #define SSH_MSG_USERAUTH_REQUEST        50
212 #define SSH_MSG_USERAUTH_FAILURE        51
213 #define SSH_MSG_USERAUTH_SUCCESS        52
214 #define SSH_MSG_USERAUTH_BANNER         53
215
216 /* User authentication protocol: method specific (reusable) (50-79) */
217
218 /* Connection protocol: generic (80-89) */
219 #define SSH_MSG_GLOBAL_REQUEST                  80
220 #define SSH_MSG_REQUEST_SUCCESS                 81
221 #define SSH_MSG_REQUEST_FAILURE                 82
222
223 /* Connection protocol: channel related messages (90-127) */
224 #define SSH_MSG_CHANNEL_OPEN                            90
225 #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION       91
226 #define SSH_MSG_CHANNEL_OPEN_FAILURE            92
227 #define SSH_MSG_CHANNEL_WINDOW_ADJUST           93
228 #define SSH_MSG_CHANNEL_DATA                            94
229 #define SSH_MSG_CHANNEL_EXTENDED_DATA           95
230 #define SSH_MSG_CHANNEL_EOF                                     96
231 #define SSH_MSG_CHANNEL_CLOSE                           97
232 #define SSH_MSG_CHANNEL_REQUEST                         98
233 #define SSH_MSG_CHANNEL_SUCCESS                         99
234 #define SSH_MSG_CHANNEL_FAILURE                         100
235
236 /* 128-191 reserved for client protocols */
237 /* 192-255 local extensions */
238
239 static const value_string ssh2_msg_vals[] = {
240         { SSH_MSG_DISCONNECT, "Disconnect" },
241         { SSH_MSG_IGNORE, "Ignore" },
242         { SSH_MSG_UNIMPLEMENTED, "Unimplemented" },
243         { SSH_MSG_DEBUG, "Debug" },
244         { SSH_MSG_SERVICE_REQUEST, "Service Request" },
245         { SSH_MSG_SERVICE_ACCEPT, "Service Accept" },
246         { SSH_MSG_KEXINIT, "Key Exchange Init" },
247         { SSH_MSG_NEWKEYS, "New Keys" },
248         { SSH_MSG_USERAUTH_REQUEST, "User Authentication Request" },
249         { SSH_MSG_USERAUTH_FAILURE, "User Authentication Failure" },
250         { SSH_MSG_USERAUTH_SUCCESS, "User Authentication Success" },
251         { SSH_MSG_USERAUTH_BANNER, "User Authentication Banner" },
252         { SSH_MSG_GLOBAL_REQUEST, "Global Request" },
253         { SSH_MSG_REQUEST_SUCCESS, "Request Success" },
254         { SSH_MSG_REQUEST_FAILURE, "Request Failure" },
255         { SSH_MSG_CHANNEL_OPEN, "Channel Open" },
256         { SSH_MSG_CHANNEL_OPEN_CONFIRMATION, "Channel Open Confirmation" },
257         { SSH_MSG_CHANNEL_OPEN_FAILURE, "Channel Open Failure" },
258         { SSH_MSG_CHANNEL_WINDOW_ADJUST, "Window Adjust" },
259         { SSH_MSG_CHANNEL_DATA, "Channel Data" },
260         { SSH_MSG_CHANNEL_EXTENDED_DATA, "Channel Extended Data" },
261         { SSH_MSG_CHANNEL_EOF, "Channel EOF" },
262         { SSH_MSG_CHANNEL_CLOSE, "Channel Close" },
263         { SSH_MSG_CHANNEL_REQUEST, "Channel Request" },
264         { SSH_MSG_CHANNEL_SUCCESS, "Channel Success" },
265         { SSH_MSG_CHANNEL_FAILURE, "Channel Failure" },
266         { 0, NULL }
267 };
268
269 static const value_string ssh2_kex_dh_msg_vals[] = {
270         { SSH_MSG_KEXDH_INIT, "Diffie-Hellman Key Exchange Init" },
271         { SSH_MSG_KEXDH_REPLY, "Diffie-Hellman Key Exchange Reply" },
272         { 0, NULL }
273 };
274
275 static const value_string ssh2_kex_dh_gex_msg_vals[] = {
276         { SSH_MSG_KEX_DH_GEX_REQUEST_OLD, "Diffie-Hellman Group Exchange Request (Old)" },
277         { SSH_MSG_KEX_DH_GEX_GROUP, "Diffie-Hellman Group Exchange Group" },
278         { SSH_MSG_KEX_DH_GEX_INIT, "Diffie-Hellman Group Exchange Init" },
279         { SSH_MSG_KEX_DH_GEX_REPLY, "Diffie-Hellman Group Exchange Reply" },
280         { SSH_MSG_KEX_DH_GEX_REQUEST, "Diffie-Hellman Group Exchange Request" },
281         { 0, NULL }
282 };
283
284 static const value_string ssh1_msg_vals[] = {
285         {SSH1_MSG_NONE, "No Message"},
286         {SSH1_MSG_DISCONNECT, "Disconnect"},
287         {SSH1_SMSG_PUBLIC_KEY, "Public Key"},
288         {SSH1_CMSG_SESSION_KEY, "Session Key"},
289         {SSH1_CMSG_USER, "User"},
290         {0, NULL}
291 };
292
293 static int ssh_dissect_key_init(tvbuff_t *tvb, int offset, proto_tree *tree,
294                 int is_response,
295                 struct ssh_flow_data *global_data);
296 static int ssh_dissect_proposal(tvbuff_t *tvb, int offset, proto_tree *tree,
297                 int hf_index_length, int hf_index_value, gchar **store);
298 static int ssh_dissect_ssh1(tvbuff_t *tvb, packet_info *pinfo,
299                 struct ssh_flow_data *global_data,
300                 int offset, proto_tree *tree, int is_response,
301                 gboolean *need_desegmentation);
302 static int ssh_dissect_ssh2(tvbuff_t *tvb, packet_info *pinfo,
303                 struct ssh_flow_data *global_data,
304                 int offset, proto_tree *tree, int is_response,
305                 gboolean *need_desegmentation);
306 static int ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo,
307                 struct ssh_flow_data *global_data,
308                 int offset, proto_tree *tree, int is_response,
309                 gboolean *need_desegmentation);
310 static int ssh_dissect_kex_dh(guint8 msg_code, tvbuff_t *tvb,
311                 packet_info *pinfo, int offset, proto_tree *tree);
312 static int ssh_dissect_kex_dh_gex(guint8 msg_code, tvbuff_t *tvb,
313                 packet_info *pinfo, int offset, proto_tree *tree);
314 static int ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo,
315                 struct ssh_flow_data *global_data,
316                 int offset, proto_tree *tree, int is_response, guint *version,
317                 gboolean *need_desegmentation);
318 static int ssh_dissect_encrypted_packet(tvbuff_t *tvb, packet_info *pinfo,
319                 struct ssh_peer_data *peer_data,
320                 int offset, proto_tree *tree);
321 static void ssh_choose_algo(gchar *client, gchar *server, gchar **result);
322 static void ssh_set_mac_length(struct ssh_peer_data *peer_data);
323 static void ssh_set_kex_specific_dissector(struct ssh_flow_data *global_data);
324
325
326 static void
327 dissect_ssh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
328 {
329
330         proto_tree      *ssh_tree = NULL;
331         proto_item      *ti;
332         conversation_t *conversation;
333         int             last_offset, offset = 0;
334
335         gboolean        is_response = (pinfo->destport != pinfo->match_uint),
336                                 need_desegmentation;
337         guint           version;
338
339         struct ssh_flow_data *global_data=NULL;
340         struct ssh_peer_data *peer_data;
341
342         conversation = find_or_create_conversation(pinfo);
343
344         global_data = (struct ssh_flow_data *)conversation_get_proto_data(conversation, proto_ssh);
345         if (!global_data) {
346                 global_data = (struct ssh_flow_data *)wmem_alloc0(wmem_file_scope(), sizeof(struct ssh_flow_data));
347                 global_data->version=SSH_VERSION_UNKNOWN;
348                 global_data->kex_specific_dissector=ssh_dissect_kex_dh;
349                 global_data->peer_data[CLIENT_PEER_DATA].mac_length=-1;
350                 global_data->peer_data[SERVER_PEER_DATA].mac_length=-1;
351
352                 conversation_add_proto_data(conversation, proto_ssh, global_data);
353         }
354
355         peer_data = &global_data->peer_data[is_response];
356
357         if (tree) {
358                   ti = proto_tree_add_item(tree, proto_ssh, tvb, offset, -1, ENC_NA);
359                   ssh_tree = proto_item_add_subtree(ti, ett_ssh);
360         }
361
362         version = global_data->version;
363
364         switch(version) {
365                 case SSH_VERSION_UNKNOWN:
366                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSH");
367                         break;
368                 case SSH_VERSION_1:
369                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv1");
370                         break;
371                 case SSH_VERSION_2:
372                         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv2");
373                         break;
374
375         }
376
377         col_clear(pinfo->cinfo, COL_INFO);
378
379         while(tvb_reported_length_remaining(tvb, offset)> 0) {
380                 gboolean after_version_start = (peer_data->frame_version_start == 0 ||
381                         pinfo->fd->num >= peer_data->frame_version_start);
382                 gboolean before_version_end = (peer_data->frame_version_end == 0 ||
383                         pinfo->fd->num <= peer_data->frame_version_end);
384
385                 need_desegmentation = FALSE;
386                 last_offset = offset;
387
388                 peer_data->counter++;
389
390                 if (after_version_start && before_version_end &&
391                           (tvb_strncaseeql(tvb, offset, "SSH-", 4) == 0)) {
392                         if (peer_data->frame_version_start == 0)
393                                 peer_data->frame_version_start = pinfo->fd->num;
394
395                         offset = ssh_dissect_protocol(tvb, pinfo,
396                                         global_data,
397                                         offset, ssh_tree, is_response,
398                                         &version, &need_desegmentation);
399
400                         if (!need_desegmentation) {
401                                 peer_data->frame_version_end = pinfo->fd->num;
402                                 global_data->version = version;
403                         }
404                 } else {
405                         switch(version) {
406
407                         case SSH_VERSION_UNKNOWN:
408                                 offset = ssh_dissect_encrypted_packet(tvb, pinfo,
409                                                 &global_data->peer_data[is_response], offset, ssh_tree);
410                                 break;
411
412                         case SSH_VERSION_1:
413                                 offset = ssh_dissect_ssh1(tvb, pinfo, global_data,
414                                                 offset, ssh_tree, is_response,
415                                                 &need_desegmentation);
416                                 break;
417
418                         case SSH_VERSION_2:
419                                 offset = ssh_dissect_ssh2(tvb, pinfo, global_data,
420                                                 offset, ssh_tree, is_response,
421                                                 &need_desegmentation);
422                                 break;
423                         }
424                 }
425
426                 if (need_desegmentation)
427                         return;
428                 if (offset <= last_offset)
429                         THROW(ReportedBoundsError);
430         }
431
432         col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s: ", is_response ? "Server" : "Client");
433 }
434
435 static int
436 ssh_dissect_ssh2(tvbuff_t *tvb, packet_info *pinfo,
437                 struct ssh_flow_data *global_data,
438                 int offset, proto_tree *tree, int is_response,
439                 gboolean *need_desegmentation)
440 {
441         proto_item *ti;
442         proto_item *ssh2_tree=NULL;
443
444         struct ssh_peer_data *peer_data = &global_data->peer_data[is_response];
445
446         if (tree) {
447                 wmem_strbuf_t *title=wmem_strbuf_new(wmem_packet_scope(), "SSH Version 2");
448
449                 if (peer_data->enc || peer_data->mac || peer_data->comp) {
450                         wmem_strbuf_append_printf(title, " (");
451                         if (peer_data->enc)
452                                 wmem_strbuf_append_printf(title, "encryption:%s%s",
453                                         peer_data->enc,
454                                         peer_data->mac || peer_data->comp
455                                                 ? " " : "");
456                         if (peer_data->mac)
457                                 wmem_strbuf_append_printf(title, "mac:%s%s",
458                                         peer_data->mac,
459                                         peer_data->comp ? " " : "");
460                         if (peer_data->comp)
461                                 wmem_strbuf_append_printf(title, "compression:%s",
462                                         peer_data->comp);
463                         wmem_strbuf_append_printf(title, ")");
464                 }
465
466                 ti=proto_tree_add_text(tree, tvb, offset, -1, "%s", wmem_strbuf_get_str(title));
467                 ssh2_tree = proto_item_add_subtree(ti, ett_ssh2);
468         }
469
470         if ((peer_data->frame_key_start == 0) ||
471                 ((peer_data->frame_key_start <= pinfo->fd->num) &&
472                 ((peer_data->frame_key_end == 0) || (pinfo->fd->num <= peer_data->frame_key_end)))) {
473                 offset = ssh_dissect_key_exchange(tvb, pinfo, global_data,
474                         offset, ssh2_tree, is_response,
475                         need_desegmentation);
476         } else {
477                 offset = ssh_dissect_encrypted_packet(tvb, pinfo,
478                                 &global_data->peer_data[is_response], offset, ssh2_tree);
479         }
480
481         return offset;
482 }
483 static int
484 ssh_dissect_ssh1(tvbuff_t *tvb, packet_info *pinfo,
485                 struct ssh_flow_data *global_data,
486                 int offset, proto_tree *tree, int is_response,
487                 gboolean *need_desegmentation)
488 {
489         guint   plen, padding_length, len;
490         guint8  msg_code;
491         guint   remain_length;
492
493         proto_item *ti;
494         proto_item *ssh1_tree =NULL;
495
496         struct ssh_peer_data *peer_data = &global_data->peer_data[is_response];
497
498         if (tree) {
499                 ti=proto_tree_add_text(tree, tvb, offset, -1, "SSH Version 1");
500                 ssh1_tree = proto_item_add_subtree(ti, ett_ssh1);
501         }
502
503         /*
504          * We use "tvb_ensure_length_remaining()" to make sure there
505          * actually *is* data remaining.
506          *
507          * This means we're guaranteed that "remain_length" is positive.
508          */
509         remain_length = tvb_ensure_length_remaining(tvb, offset);
510         /*
511          * Can we do reassembly?
512          */
513         if (ssh_desegment && pinfo->can_desegment) {
514                 /*
515                  * Yes - would an SSH header starting at this offset be split
516                  * across segment boundaries?
517                  */
518                 if (remain_length < 4) {
519                         /*
520                          * Yes.  Tell the TCP dissector where the data for
521                          * this message starts in the data it handed us and
522                          * that we need "some more data."  Don't tell it
523                          * exactly how many bytes we need because if/when we
524                          * ask for even more (after the header) that will
525                          * break reassembly.
526                          */
527                         pinfo->desegment_offset = offset;
528                         pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
529                         *need_desegmentation = TRUE;
530                         return offset;
531                 }
532         }
533         plen = tvb_get_ntohl(tvb, offset) ;
534         padding_length  = 8 - plen%8;
535
536
537         if (ssh_desegment && pinfo->can_desegment) {
538                 if (plen+4+padding_length >  remain_length) {
539                         pinfo->desegment_offset = offset;
540                         pinfo->desegment_len = plen+padding_length - remain_length;
541                         *need_desegmentation = TRUE;
542                         return offset;
543                 }
544         }
545
546         if (plen >= 0xffff) {
547                 if (ssh1_tree && plen > 0) {
548                           proto_tree_add_uint_format(ssh1_tree, hf_ssh_packet_length, tvb,
549                             offset, 4, plen, "Overly large length %x", plen);
550                 }
551                 plen = remain_length-4-padding_length;
552         } else {
553                 if (ssh1_tree && plen > 0) {
554                           proto_tree_add_uint(ssh1_tree, hf_ssh_packet_length, tvb,
555                             offset, 4, plen);
556                 }
557         }
558         offset+=4;
559 /* padding length */
560
561         if (tree) {
562                   proto_tree_add_uint(ssh1_tree, hf_ssh_padding_length, tvb,
563                     offset, padding_length, padding_length);
564         }
565         offset += padding_length;
566
567         /* msg_code */
568         if ((peer_data->frame_key_start == 0) ||
569                 ((peer_data->frame_key_start >= pinfo->fd->num) && (pinfo->fd->num <= peer_data->frame_key_end))) {
570                 msg_code = tvb_get_guint8(tvb, offset);
571
572                 proto_tree_add_item(ssh1_tree, hf_ssh_msg_code, tvb, offset, 1, ENC_NA);
573                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
574                         val_to_str(msg_code, ssh1_msg_vals, "Unknown (%u)"));
575                 offset += 1;
576                 len = plen -1;
577                 if (!pinfo->fd->flags.visited) {
578                         if (peer_data->frame_key_start == 0)
579                                 peer_data->frame_key_start = pinfo->fd->num;
580                         peer_data->frame_key_end = pinfo->fd->num;
581                 }
582         } else {
583                 len = plen;
584                 col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Encrypted packet (len=%d)", len);
585         }
586         /* payload */
587         if (ssh1_tree) {
588                 proto_tree_add_item(ssh1_tree, hf_ssh_payload,
589                     tvb, offset, len, ENC_NA);
590         }
591         offset+=len;
592
593         return offset;
594 }
595
596 static int
597 ssh_tree_add_mpint(tvbuff_t *tvb, int offset, proto_tree *tree,
598         int hf_ssh_mpint_selection)
599 {
600         guint len = tvb_get_ntohl(tvb, offset);
601         if (tree) {
602                 proto_tree_add_uint(tree, hf_ssh_mpint_length, tvb,
603                         offset, 4, len);
604         }
605         offset+=4;
606         if (tree) {
607                 proto_tree_add_item(tree, hf_ssh_mpint_selection,
608                         tvb, offset, len, ENC_NA);
609         }
610         return 4+len;
611 }
612
613 static int
614 ssh_tree_add_string(tvbuff_t *tvb, int offset, proto_tree *tree,
615         int hf_ssh_string, int hf_ssh_string_length)
616 {
617         guint len = tvb_get_ntohl(tvb, offset);
618         if (tree) {
619                 proto_tree_add_uint(tree, hf_ssh_string_length, tvb,
620                         offset, 4, len);
621         }
622         offset+=4;
623         if (tree) {
624                 proto_tree_add_item(tree, hf_ssh_string,
625                         tvb, offset, len, ENC_NA);
626         }
627         return 4+len;
628 }
629
630 static int
631 ssh_dissect_key_exchange(tvbuff_t *tvb, packet_info *pinfo,
632                 struct ssh_flow_data *global_data,
633                 int offset, proto_tree *tree, int is_response,
634                 gboolean *need_desegmentation)
635 {
636         guint   plen, len;
637         guint8  padding_length;
638         guint   remain_length;
639         int     last_offset=offset;
640         guint   msg_code;
641
642         proto_item *tf, *ti;
643         proto_item *key_ex_tree =NULL;
644
645         struct ssh_peer_data *peer_data = &global_data->peer_data[is_response];
646
647         /*
648          * We use "tvb_ensure_length_remaining()" to make sure there
649          * actually *is* data remaining.
650          *
651          * This means we're guaranteed that "remain_length" is positive.
652          */
653         remain_length = tvb_ensure_length_remaining(tvb, offset);
654         /*
655          * Can we do reassembly?
656          */
657         if (ssh_desegment && pinfo->can_desegment) {
658                 /*
659                  * Yes - would an SSH header starting at this offset
660                  * be split across segment boundaries?
661                  */
662                 if (remain_length < 4) {
663                         /*
664                          * Yes.  Tell the TCP dissector where the data for
665                          * this message starts in the data it handed us and
666                          * that we need "some more data."  Don't tell it
667                          * exactly how many bytes we need because if/when we
668                          * ask for even more (after the header) that will
669                          * break reassembly.
670                          */
671                         pinfo->desegment_offset = offset;
672                         pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
673                         *need_desegmentation = TRUE;
674                         return offset;
675                 }
676         }
677         plen = tvb_get_ntohl(tvb, offset) ;
678
679         if (ssh_desegment && pinfo->can_desegment) {
680                 if (plen +4 >  remain_length) {
681                         pinfo->desegment_offset = offset;
682                         pinfo->desegment_len = plen+4 - remain_length;
683                         *need_desegmentation = TRUE;
684                         return offset;
685                 }
686         }
687         /*
688          * Need to check plen > 0x80000000 here
689          */
690
691         ti = proto_tree_add_uint(tree, hf_ssh_packet_length, tvb,
692                                         offset, 4, plen);
693         if (plen >= 0xffff) {
694                 expert_add_info_format(pinfo, ti, &ei_ssh_packet_length, "Overly large number %d", plen);
695                 plen = remain_length-4;
696         }
697         offset+=4;
698
699         /* padding length */
700         padding_length = tvb_get_guint8(tvb, offset);
701         proto_tree_add_uint(tree, hf_ssh_padding_length, tvb, offset, 1, padding_length);
702         offset += 1;
703
704         tf=proto_tree_add_text(tree, tvb, offset, -1, "Key Exchange");
705         key_ex_tree = proto_item_add_subtree(tf, ett_key_exchange);
706
707         /* msg_code */
708         msg_code = tvb_get_guint8(tvb, offset);
709
710         if (msg_code >= 30 && msg_code < 40) {
711                 offset = global_data->kex_specific_dissector(msg_code, tvb, pinfo, offset, key_ex_tree);
712         } else {
713                 proto_tree_add_item(key_ex_tree, hf_ssh2_msg_code, tvb, offset, 1, ENC_NA);
714                 offset += 1;
715
716                 col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
717                         val_to_str(msg_code, ssh2_msg_vals, "Unknown (%u)"));
718
719                 /* 16 bytes cookie  */
720                 switch(msg_code)
721                 {
722                 case SSH_MSG_KEXINIT:
723                         if ((peer_data->frame_key_start == 0) || (peer_data->frame_key_start == pinfo->fd->num)) {
724                                 offset = ssh_dissect_key_init(tvb, offset, key_ex_tree, is_response, global_data);
725                                 peer_data->frame_key_start = pinfo->fd->num;
726                         }
727                         break;
728                 case SSH_MSG_NEWKEYS:
729                         if (peer_data->frame_key_end == 0) {
730                                 peer_data->frame_key_end = pinfo->fd->num;
731                                 ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].enc_proposals[is_response],
732                                                                 global_data->peer_data[SERVER_PEER_DATA].enc_proposals[is_response],
733                                                                 &peer_data->enc);
734
735                                 /* some ciphers have their own MAC so the "negotiated" one is meaningless */
736                                 if(peer_data->enc && (0 == strcmp(peer_data->enc, "aes128-gcm@openssh.com") ||
737                                                                           0 == strcmp(peer_data->enc, "aes256-gcm@openssh.com"))) {
738                                         peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>");
739                                         peer_data->mac_length = 16;
740                                         peer_data->length_is_plaintext = 1;
741                                 }
742                                 else if(peer_data->enc && 0 == strcmp(peer_data->enc, "chacha20-poly1305@openssh.com")) {
743                                         peer_data->mac = wmem_strdup(wmem_file_scope(), (const gchar *)"<implicit>");
744                                         peer_data->mac_length = 16;
745                                 }
746                                 else {
747                                         ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].mac_proposals[is_response],
748                                                                         global_data->peer_data[SERVER_PEER_DATA].mac_proposals[is_response],
749                                                                         &peer_data->mac);
750                                         ssh_set_mac_length(peer_data);
751                                 }
752
753                                 ssh_choose_algo(global_data->peer_data[CLIENT_PEER_DATA].comp_proposals[is_response],
754                                                                 global_data->peer_data[SERVER_PEER_DATA].comp_proposals[is_response],
755                                                                 &peer_data->comp);
756                         }
757                         break;
758                 }
759         }
760
761         len = plen+4-padding_length-(offset-last_offset);
762         proto_tree_add_item(key_ex_tree, hf_ssh_payload, tvb, offset, len, ENC_NA);
763         offset +=len;
764
765         /* padding */
766         proto_tree_add_item(key_ex_tree, hf_ssh_padding_string, tvb, offset, padding_length, ENC_NA);
767         offset+= padding_length;
768
769         return offset;
770 }
771
772 static int ssh_dissect_kex_dh(guint8 msg_code, tvbuff_t *tvb,
773                 packet_info *pinfo, int offset, proto_tree *tree)
774 {
775         proto_tree_add_item(tree, hf_ssh2_kex_dh_msg_code, tvb, offset, 1, ENC_NA);
776         offset += 1;
777
778         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
779                 val_to_str(msg_code, ssh2_kex_dh_msg_vals, "Unknown (%u)"));
780
781         switch (msg_code) {
782         case SSH_MSG_KEXDH_INIT:
783                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e);
784                 break;
785
786         case SSH_MSG_KEXDH_REPLY:
787                 offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length);
788                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f);
789                 offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length);
790                 break;
791         }
792
793         return offset;
794 }
795
796 static int ssh_dissect_kex_dh_gex(guint8 msg_code, tvbuff_t *tvb,
797                 packet_info *pinfo, int offset, proto_tree *tree)
798 {
799         proto_tree_add_item(tree, hf_ssh2_kex_dh_gex_msg_code, tvb, offset, 1, ENC_NA);
800         offset += 1;
801
802         col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
803                 val_to_str(msg_code, ssh2_kex_dh_gex_msg_vals, "Unknown (%u)"));
804
805         switch (msg_code) {
806         case SSH_MSG_KEX_DH_GEX_REQUEST_OLD:
807                 proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN);
808                 offset += 4;
809                 break;
810
811         case SSH_MSG_KEX_DH_GEX_GROUP:
812                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_p);
813                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_g);
814                 break;
815
816         case SSH_MSG_KEX_DH_GEX_INIT:
817                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_e);
818                 break;
819
820         case SSH_MSG_KEX_DH_GEX_REPLY:
821                 offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_host_key, hf_ssh_kexdh_host_key_length);
822                 offset += ssh_tree_add_mpint(tvb, offset, tree, hf_ssh_mpint_f);
823                 offset += ssh_tree_add_string(tvb, offset, tree, hf_ssh_kexdh_h_sig, hf_ssh_kexdh_h_sig_length);
824                 break;
825
826         case SSH_MSG_KEX_DH_GEX_REQUEST:
827                 proto_tree_add_item(tree, hf_ssh_dh_gex_min, tvb, offset, 4, ENC_BIG_ENDIAN);
828                 offset += 4;
829                 proto_tree_add_item(tree, hf_ssh_dh_gex_nbits, tvb, offset, 4, ENC_BIG_ENDIAN);
830                 offset += 4;
831                 proto_tree_add_item(tree, hf_ssh_dh_gex_max, tvb, offset, 4, ENC_BIG_ENDIAN);
832                 offset += 4;
833                 break;
834         }
835
836         return offset;
837 }
838
839 static int
840 ssh_dissect_encrypted_packet(tvbuff_t *tvb, packet_info *pinfo,
841                 struct ssh_peer_data *peer_data,
842                 int offset, proto_tree *tree)
843 {
844         gint len;
845         guint plen;
846
847         len = tvb_reported_length_remaining(tvb, offset);
848         col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Encrypted packet (len=%d)", len);
849
850         if (tree) {
851                 gint encrypted_len = len;
852
853                 if (len > 4 && peer_data->length_is_plaintext) {
854                         plen = tvb_get_ntohl(tvb, offset) ;
855                         proto_tree_add_uint(tree, hf_ssh_packet_length, tvb, offset, 4, plen);
856                         encrypted_len -= 4;
857                 }
858                 else if (len > 4) {
859                         proto_tree_add_item(tree, hf_ssh_packet_length_encrypted, tvb, offset, 4, ENC_NA);
860                         encrypted_len -= 4;
861                 }
862
863                 if (peer_data->mac_length>0)
864                         encrypted_len -= peer_data->mac_length;
865
866                 proto_tree_add_item(tree, hf_ssh_encrypted_packet,
867                                         tvb, offset+4, encrypted_len, ENC_NA);
868
869                 if (peer_data->mac_length>0)
870                         proto_tree_add_item(tree, hf_ssh_mac_string,
871                                 tvb, offset+4+encrypted_len,
872                                 peer_data->mac_length, ENC_NA);
873         }
874         offset+=len;
875         return offset;
876 }
877
878 static int
879 ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo,
880                 struct ssh_flow_data *global_data,
881                 int offset, proto_tree *tree, int is_response, guint * version,
882                 gboolean *need_desegmentation)
883 {
884         guint   remain_length;
885         gint    linelen, protolen;
886
887         /*
888          *  If the first packet do not contain the banner,
889          *  it is dump in the middle of a flow or not a ssh at all
890          */
891         if (tvb_strncaseeql(tvb, offset, "SSH-", 4) != 0) {
892                 offset = ssh_dissect_encrypted_packet(tvb, pinfo,
893                         &global_data->peer_data[is_response], offset, tree);
894                 return offset;
895         }
896
897         if (!is_response) {
898                 if (tvb_strncaseeql(tvb, offset, "SSH-2.", 6) == 0) {
899                         *(version) = SSH_VERSION_2;
900                 } else if (tvb_strncaseeql(tvb, offset, "SSH-1.99-", 9) == 0) {
901                         *(version) = SSH_VERSION_2;
902                 } else if (tvb_strncaseeql(tvb, offset, "SSH-1.", 6) == 0) {
903                         *(version) = SSH_VERSION_1;
904                 }
905         }
906
907         /*
908          * We use "tvb_ensure_length_remaining()" to make sure there
909          * actually *is* data remaining.
910          *
911          * This means we're guaranteed that "remain_length" is positive.
912          */
913         remain_length = tvb_ensure_length_remaining(tvb, offset);
914         /*linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
915          */
916         linelen = tvb_find_guint8(tvb, offset, -1, '\n');
917
918         if (ssh_desegment && pinfo->can_desegment) {
919                 if (linelen == -1 || remain_length < (guint)linelen-offset) {
920                         pinfo->desegment_offset = offset;
921                         pinfo->desegment_len = linelen-remain_length;
922                         *need_desegmentation = TRUE;
923                         return offset;
924                 }
925         }
926         if (linelen == -1) {
927                 /* XXX - reassemble across segment boundaries? */
928                 linelen = remain_length;
929                 protolen = linelen;
930         } else {
931                 linelen = linelen - offset + 1;
932
933                 if (linelen > 1 && tvb_get_guint8(tvb, offset + linelen - 2) == '\r')
934                         protolen = linelen - 2;
935                 else
936                         protolen = linelen - 1;
937         }
938
939         col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Protocol (%s)",
940                         tvb_format_text(tvb, offset, protolen));
941
942         proto_tree_add_item(tree, hf_ssh_protocol,
943                                         tvb, offset, linelen, ENC_ASCII|ENC_NA);
944         offset+=linelen;
945         return offset;
946 }
947
948 static void
949 ssh_set_mac_length(struct ssh_peer_data *peer_data)
950 {
951         char *size_str;
952         guint size=0;
953         char *mac_name = peer_data->mac;
954         char *strip;
955
956         if (!mac_name) return;
957         mac_name = wmem_strdup(NULL, (const gchar *)mac_name);
958         if (!mac_name) return;
959
960         /* strip trailing "-etm@openssh.com" or "@openssh.com" */
961         strip = strstr(mac_name, "-etm@openssh.com");
962         if (strip) {
963                 peer_data->length_is_plaintext = 1;
964                 *strip = '\0';
965         }
966         else {
967                 strip = strstr(mac_name, "@openssh.com");
968                 if (strip) *strip = '\0';
969         }
970
971         if ((size_str=g_strrstr(mac_name, "-")) && ((size=atoi(size_str+1)))) {
972                 peer_data->mac_length = (size > 0) ? size / 8 : 0;
973         }
974         else if (strcmp(mac_name, "hmac-sha1") == 0) {
975                 peer_data->mac_length = 20;
976         }
977         else if (strcmp(mac_name, "hmac-md5") == 0) {
978                 peer_data->mac_length = 16;
979         }
980         else if (strcmp(mac_name, "hmac-ripemd160") == 0) {
981                 peer_data->mac_length = 20;
982         }
983         else if (strcmp(mac_name, "none") == 0) {
984                 peer_data->mac_length = 0;
985         }
986
987         wmem_free(NULL, mac_name);
988 }
989
990 static void ssh_set_kex_specific_dissector(struct ssh_flow_data *global_data)
991 {
992         const char *kex_name = global_data->kex;
993
994         if (!kex_name) return;
995
996         if (strcmp(kex_name, "diffie-hellman-group-exchange-sha1") == 0 ||
997                 strcmp(kex_name, "diffie-hellman-group-exchange-sha256") == 0)
998         {
999                 global_data->kex_specific_dissector = ssh_dissect_kex_dh_gex;
1000         }
1001 }
1002
1003 static gint
1004 ssh_gslist_compare_strings(gconstpointer a, gconstpointer b)
1005 {
1006         if (a == NULL && b == NULL)
1007                 return 0;
1008         if (a == NULL)
1009                 return -1;
1010         if (b == NULL)
1011                 return 1;
1012         return strcmp((const char*)a, (const char*)b);
1013 }
1014
1015 /* expects that *result is NULL */
1016 static void
1017 ssh_choose_algo(gchar *client, gchar *server, gchar **result)
1018 {
1019         gchar **server_strings=NULL;
1020         gchar **client_strings=NULL;
1021         gchar **step;
1022         GSList *server_list = NULL;
1023
1024         if (!client || !server || !result || *result)
1025                 return;
1026
1027         server_strings = g_strsplit(server, ",", 0);
1028         for (step = server_strings; *step; step++) {
1029                 server_list = g_slist_append(server_list, *step);
1030         }
1031
1032         client_strings = g_strsplit(client, ",", 0);
1033         for (step = client_strings; *step; step++) {
1034                 GSList *agreed;
1035                 if ((agreed=g_slist_find_custom(server_list, *step, ssh_gslist_compare_strings))) {
1036                         *result = wmem_strdup(wmem_file_scope(), (const gchar *)agreed->data);
1037                         break;
1038                 }
1039         }
1040
1041         g_strfreev(client_strings);
1042         g_slist_free(server_list);
1043         g_strfreev(server_strings);
1044 }
1045
1046 static int
1047 ssh_dissect_key_init(tvbuff_t *tvb, int offset, proto_tree *tree,
1048                 int is_response, struct ssh_flow_data *global_data)
1049 {
1050         int start_offset = offset;
1051
1052         proto_item *tf = NULL;
1053         proto_item *key_init_tree=NULL;
1054
1055         struct ssh_peer_data *peer_data = &global_data->peer_data[is_response];
1056
1057         if (tree) {
1058                 tf=proto_tree_add_text(tree, tvb, offset, -1, "Algorithms");
1059                 key_init_tree = proto_item_add_subtree(tf, ett_key_init);
1060                 proto_tree_add_item(key_init_tree, hf_ssh_cookie,
1061                                     tvb, offset, 16, ENC_NA);
1062         }
1063         offset += 16;
1064
1065         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1066                 hf_ssh_kex_algorithms_length, hf_ssh_kex_algorithms,
1067                 &peer_data->kex_proposal);
1068         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1069                 hf_ssh_server_host_key_algorithms_length,
1070                 hf_ssh_server_host_key_algorithms, NULL);
1071         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1072                 hf_ssh_encryption_algorithms_client_to_server_length,
1073                 hf_ssh_encryption_algorithms_client_to_server,
1074                 &peer_data->enc_proposals[CLIENT_TO_SERVER_PROPOSAL]);
1075         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1076                 hf_ssh_encryption_algorithms_server_to_client_length,
1077                 hf_ssh_encryption_algorithms_server_to_client,
1078                 &peer_data->enc_proposals[SERVER_TO_CLIENT_PROPOSAL]);
1079         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1080                 hf_ssh_mac_algorithms_client_to_server_length,
1081                 hf_ssh_mac_algorithms_client_to_server,
1082                 &peer_data->mac_proposals[CLIENT_TO_SERVER_PROPOSAL]);
1083         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1084                 hf_ssh_mac_algorithms_server_to_client_length,
1085                 hf_ssh_mac_algorithms_server_to_client,
1086                 &peer_data->mac_proposals[SERVER_TO_CLIENT_PROPOSAL]);
1087         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1088                 hf_ssh_compression_algorithms_client_to_server_length,
1089                 hf_ssh_compression_algorithms_client_to_server,
1090                 &peer_data->comp_proposals[CLIENT_TO_SERVER_PROPOSAL]);
1091         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1092                 hf_ssh_compression_algorithms_server_to_client_length,
1093                 hf_ssh_compression_algorithms_server_to_client,
1094                 &peer_data->comp_proposals[SERVER_TO_CLIENT_PROPOSAL]);
1095         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1096                 hf_ssh_languages_client_to_server_length,
1097                 hf_ssh_languages_client_to_server, NULL);
1098         offset = ssh_dissect_proposal(tvb, offset, key_init_tree,
1099                 hf_ssh_languages_server_to_client_length,
1100                 hf_ssh_languages_server_to_client, NULL);
1101
1102         proto_tree_add_item(key_init_tree, hf_ssh_kex_first_packet_follows,
1103                 tvb, offset, 1, ENC_BIG_ENDIAN);
1104         offset+=1;
1105
1106         proto_tree_add_item(key_init_tree, hf_ssh_kex_reserved,
1107                 tvb, offset, 4, ENC_NA);
1108         offset+=4;
1109
1110         if (global_data->peer_data[CLIENT_PEER_DATA].kex_proposal &&
1111                 global_data->peer_data[SERVER_PEER_DATA].kex_proposal &&
1112                 !global_data->kex)
1113         {
1114                 /* Note: we're ignoring first_kex_packet_follows. */
1115                 ssh_choose_algo(
1116                         global_data->peer_data[CLIENT_PEER_DATA].kex_proposal,
1117                         global_data->peer_data[SERVER_PEER_DATA].kex_proposal,
1118                         &global_data->kex);
1119                 ssh_set_kex_specific_dissector(global_data);
1120         }
1121
1122         if (tf != NULL) {
1123                 proto_item_set_len(tf, offset-start_offset);
1124         }
1125
1126         return offset;
1127 }
1128
1129 static int
1130 ssh_dissect_proposal(tvbuff_t *tvb, int offset, proto_tree *tree,
1131                      int hf_index_length, int hf_index_value, gchar **store)
1132 {
1133         guint32 len = tvb_get_ntohl(tvb, offset);
1134         proto_tree_add_uint(tree, hf_index_length, tvb, offset, 4, len);
1135         offset += 4;
1136
1137         proto_tree_add_item(tree, hf_index_value, tvb, offset, len,
1138                                 ENC_ASCII);
1139         if (store)
1140                 *store = tvb_get_string_enc(wmem_file_scope(), tvb, offset, len, ENC_ASCII);
1141         offset += len;
1142
1143         return offset;
1144 }
1145
1146
1147 void
1148 proto_register_ssh(void)
1149 {
1150         static hf_register_info hf[] = {
1151                 { &hf_ssh_packet_length,
1152                   { "Packet Length",      "ssh.packet_length",
1153                     FT_UINT32, BASE_DEC, NULL,  0x0,
1154                     "SSH packet length", HFILL }},
1155
1156                 { &hf_ssh_packet_length_encrypted,
1157                   { "Packet Length (encrypted)",      "ssh.packet_length_encrypted",
1158                     FT_BYTES, BASE_NONE, NULL,  0x0,
1159                     "SSH packet length (encrypted)", HFILL }},
1160
1161                 { &hf_ssh_padding_length,
1162                   { "Padding Length",  "ssh.padding_length",
1163                     FT_UINT8, BASE_DEC, NULL, 0x0,
1164                     "SSH Packet Number", HFILL }},
1165
1166                 { &hf_ssh_msg_code,
1167                   { "Message Code",  "ssh.message_code",
1168                     FT_UINT8, BASE_DEC, VALS(ssh1_msg_vals), 0x0,
1169                     "SSH Message Code", HFILL }},
1170
1171                 { &hf_ssh2_msg_code,
1172                   { "Message Code",  "ssh.message_code",
1173                     FT_UINT8, BASE_DEC, VALS(ssh2_msg_vals), 0x0,
1174                     "SSH Message Code", HFILL }},
1175
1176                 { &hf_ssh2_kex_dh_msg_code,
1177                   { "Message Code",  "ssh.message_code",
1178                     FT_UINT8, BASE_DEC, VALS(ssh2_kex_dh_msg_vals), 0x0,
1179                     "SSH Message Code", HFILL }},
1180
1181                 { &hf_ssh2_kex_dh_gex_msg_code,
1182                   { "Message Code",  "ssh.message_code",
1183                     FT_UINT8, BASE_DEC, VALS(ssh2_kex_dh_gex_msg_vals), 0x0,
1184                     "SSH Message Code", HFILL }},
1185
1186                 { &hf_ssh_mpint_g,
1187                   { "DH base (G)",  "ssh.dh.g",
1188                     FT_BYTES, BASE_NONE, NULL, 0x0,
1189                     "SSH DH base (G)", HFILL }},
1190
1191                 { &hf_ssh_mpint_p,
1192                   { "DH modulus (P)",  "ssh.dh.p",
1193                     FT_BYTES, BASE_NONE, NULL, 0x0,
1194                     "SSH DH modulus (P)", HFILL }},
1195
1196                 { &hf_ssh_mpint_e,
1197                   { "DH client e",  "ssh.dh.e",
1198                     FT_BYTES, BASE_NONE, NULL, 0x0,
1199                     "SSH DH client e", HFILL }},
1200
1201                 { &hf_ssh_mpint_f,
1202                   { "DH server f",  "ssh.dh.f",
1203                     FT_BYTES, BASE_NONE, NULL, 0x0,
1204                     "SSH DH server f", HFILL }},
1205
1206                 { &hf_ssh_mpint_length,
1207                   { "Multi Precision Integer Length",      "ssh.mpint_length",
1208                     FT_UINT32, BASE_DEC, NULL,  0x0,
1209                     "SSH mpint length", HFILL }},
1210
1211                 { &hf_ssh_kexdh_host_key,
1212                   { "KEX DH host key",         "ssh.kexdh.host_key",
1213                     FT_BYTES, BASE_NONE, NULL, 0x0,
1214                     "SSH KEX DH host key", HFILL }},
1215
1216                 { &hf_ssh_kexdh_h_sig,
1217                   { "KEX DH H signature",         "ssh.kexdh.h_sig",
1218                     FT_BYTES, BASE_NONE, NULL, 0x0,
1219                     "SSH KEX DH H signature", HFILL }},
1220
1221                 { &hf_ssh_kexdh_host_key_length,
1222                   { "KEX DH host key length",         "ssh.kexdh.host_key_length",
1223                     FT_UINT32, BASE_DEC, NULL, 0x0,
1224                     "SSH KEX DH host key length", HFILL }},
1225
1226                 { &hf_ssh_kexdh_h_sig_length,
1227                   { "KEX DH H signature length",         "ssh.kexdh.h_sig_length",
1228                     FT_UINT32, BASE_DEC, NULL, 0x0,
1229                     "SSH KEX DH H signature length", HFILL }},
1230
1231                 { &hf_ssh_encrypted_packet,
1232                   { "Encrypted Packet",  "ssh.encrypted_packet",
1233                     FT_BYTES, BASE_NONE, NULL, 0x0,
1234                     "SSH Protocol Packet", HFILL }},
1235
1236                 { &hf_ssh_protocol,
1237                   { "Protocol",  "ssh.protocol",
1238                     FT_STRING, BASE_NONE, NULL, 0x0,
1239                     "SSH Protocol", HFILL }},
1240
1241                 { &hf_ssh_cookie,
1242                   { "Cookie",  "ssh.cookie",
1243                     FT_BYTES, BASE_NONE, NULL, 0x0,
1244                     "SSH Cookie", HFILL }},
1245
1246                 { &hf_ssh_kex_first_packet_follows,
1247                   { "KEX First Packet Follows",      "ssh.kex.first_packet_follows",
1248                     FT_UINT8, BASE_DEC, NULL, 0x0,
1249                     "SSH KEX Fist Packet Follows", HFILL }},
1250
1251                 { &hf_ssh_kex_reserved,
1252                   { "Reserved",  "ssh.kex.reserved",
1253                     FT_BYTES, BASE_NONE, NULL, 0x0,
1254                     "SSH Protocol KEX Reserved", HFILL }},
1255
1256                 { &hf_ssh_dh_gex_min,
1257                   { "DH GEX Min",  "ssh.dh_gex.min",
1258                     FT_UINT32, BASE_DEC, NULL, 0x0,
1259                     "SSH DH GEX Minimum", HFILL }},
1260
1261                 { &hf_ssh_dh_gex_nbits,
1262                   { "DH GEX Numbers of Bits",  "ssh.dh_gex.nbits",
1263                     FT_UINT32, BASE_DEC, NULL, 0x0,
1264                     "SSH DH GEX Number of Bits", HFILL }},
1265
1266                 { &hf_ssh_dh_gex_max,
1267                   { "DH GEX Max",  "ssh.dh_gex.max",
1268                     FT_UINT32, BASE_DEC, NULL, 0x0,
1269                     "SSH DH GEX Maximum", HFILL }},
1270
1271                 { &hf_ssh_payload,
1272                   { "Payload",  "ssh.payload",
1273                     FT_BYTES, BASE_NONE, NULL, 0x0,
1274                     "SSH Payload", HFILL }},
1275
1276                 { &hf_ssh_padding_string,
1277                   { "Padding String",  "ssh.padding_string",
1278                     FT_BYTES, BASE_NONE, NULL, 0x0,
1279                     "SSH Padding String", HFILL }},
1280
1281                 { &hf_ssh_mac_string,
1282                   { "MAC",  "ssh.mac",
1283                     FT_BYTES, BASE_NONE, NULL, 0x0,
1284                     "SSH Protocol Packet MAC", HFILL }},
1285
1286                 { &hf_ssh_kex_algorithms,
1287                   { "kex_algorithms string",         "ssh.kex_algorithms",
1288                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1289                     "SSH kex_algorithms string", HFILL }},
1290
1291                 { &hf_ssh_server_host_key_algorithms,
1292                   { "server_host_key_algorithms string",         "ssh.server_host_key_algorithms",
1293                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1294                     "SSH server_host_key_algorithms string", HFILL }},
1295
1296                 { &hf_ssh_encryption_algorithms_client_to_server,
1297                   { "encryption_algorithms_client_to_server string",         "ssh.encryption_algorithms_client_to_server",
1298                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1299                     "SSH encryption_algorithms_client_to_server string", HFILL }},
1300
1301                 { &hf_ssh_encryption_algorithms_server_to_client,
1302                   { "encryption_algorithms_server_to_client string",         "ssh.encryption_algorithms_server_to_client",
1303                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1304                     "SSH encryption_algorithms_server_to_client string", HFILL }},
1305
1306                 { &hf_ssh_mac_algorithms_client_to_server,
1307                   { "mac_algorithms_client_to_server string",         "ssh.mac_algorithms_client_to_server",
1308                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1309                     "SSH mac_algorithms_client_to_server string", HFILL }},
1310
1311                 { &hf_ssh_mac_algorithms_server_to_client,
1312                   { "mac_algorithms_server_to_client string",         "ssh.mac_algorithms_server_to_client",
1313                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1314                     "SSH mac_algorithms_server_to_client string", HFILL }},
1315
1316                 { &hf_ssh_compression_algorithms_client_to_server,
1317                   { "compression_algorithms_client_to_server string",         "ssh.compression_algorithms_client_to_server",
1318                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1319                     "SSH compression_algorithms_client_to_server string", HFILL }},
1320
1321                 { &hf_ssh_compression_algorithms_server_to_client,
1322                   { "compression_algorithms_server_to_client string",         "ssh.compression_algorithms_server_to_client",
1323                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1324                     "SSH compression_algorithms_server_to_client string", HFILL }},
1325
1326                 { &hf_ssh_languages_client_to_server,
1327                   { "languages_client_to_server string",         "ssh.languages_client_to_server",
1328                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1329                     "SSH languages_client_to_server string", HFILL }},
1330
1331                 { &hf_ssh_languages_server_to_client,
1332                   { "languages_server_to_client string",         "ssh.languages_server_to_client",
1333                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
1334                     "SSH languages_server_to_client string", HFILL }},
1335
1336                 { &hf_ssh_kex_algorithms_length,
1337                   { "kex_algorithms length",         "ssh.kex_algorithms_length",
1338                     FT_UINT32, BASE_DEC, NULL, 0x0,
1339                     "SSH kex_algorithms length", HFILL }},
1340
1341                 { &hf_ssh_server_host_key_algorithms_length,
1342                   { "server_host_key_algorithms length",         "ssh.server_host_key_algorithms_length",
1343                     FT_UINT32, BASE_DEC, NULL, 0x0,
1344                     "SSH server_host_key_algorithms length", HFILL }},
1345
1346                 { &hf_ssh_encryption_algorithms_client_to_server_length,
1347                   { "encryption_algorithms_client_to_server length",         "ssh.encryption_algorithms_client_to_server_length",
1348                     FT_UINT32, BASE_DEC, NULL, 0x0,
1349                     "SSH encryption_algorithms_client_to_server length", HFILL }},
1350
1351                 { &hf_ssh_encryption_algorithms_server_to_client_length,
1352                   { "encryption_algorithms_server_to_client length",         "ssh.encryption_algorithms_server_to_client_length",
1353                     FT_UINT32, BASE_DEC, NULL, 0x0,
1354                     "SSH encryption_algorithms_server_to_client length", HFILL }},
1355
1356                 { &hf_ssh_mac_algorithms_client_to_server_length,
1357                   { "mac_algorithms_client_to_server length",         "ssh.mac_algorithms_client_to_server_length",
1358                     FT_UINT32, BASE_DEC, NULL, 0x0,
1359                     "SSH mac_algorithms_client_to_server length", HFILL }},
1360
1361                 { &hf_ssh_mac_algorithms_server_to_client_length,
1362                   { "mac_algorithms_server_to_client length",         "ssh.mac_algorithms_server_to_client_length",
1363                     FT_UINT32, BASE_DEC, NULL, 0x0,
1364                     "SSH mac_algorithms_server_to_client length", HFILL }},
1365
1366                 { &hf_ssh_compression_algorithms_client_to_server_length,
1367                   { "compression_algorithms_client_to_server length",         "ssh.compression_algorithms_client_to_server_length",
1368                     FT_UINT32, BASE_DEC, NULL, 0x0,
1369                     "SSH compression_algorithms_client_to_server length", HFILL }},
1370
1371                 { &hf_ssh_compression_algorithms_server_to_client_length,
1372                   { "compression_algorithms_server_to_client length",         "ssh.compression_algorithms_server_to_client_length",
1373                     FT_UINT32, BASE_DEC, NULL, 0x0,
1374                     "SSH compression_algorithms_server_to_client length", HFILL }},
1375
1376                 { &hf_ssh_languages_client_to_server_length,
1377                   { "languages_client_to_server length",         "ssh.languages_client_to_server_length",
1378                     FT_UINT32, BASE_DEC, NULL, 0x0,
1379                     "SSH languages_client_to_server length", HFILL }},
1380
1381                 { &hf_ssh_languages_server_to_client_length,
1382                   { "languages_server_to_client length",         "ssh.languages_server_to_client_length",
1383                     FT_UINT32, BASE_DEC, NULL, 0x0,
1384                     "SSH languages_server_to_client length", HFILL }},
1385         };
1386
1387         static gint *ett[] = {
1388                 &ett_ssh,
1389                 &ett_key_exchange,
1390                 &ett_ssh1,
1391                 &ett_ssh2,
1392                 &ett_key_init
1393         };
1394
1395         static ei_register_info ei[] = {
1396                 { &ei_ssh_packet_length, { "ssh.packet_length.error", PI_PROTOCOL, PI_WARN, "Overly large number", EXPFILL }},
1397         };
1398
1399         module_t *ssh_module;
1400         expert_module_t *expert_ssh;
1401
1402         proto_ssh = proto_register_protocol("SSH Protocol", "SSH", "ssh");
1403         proto_register_field_array(proto_ssh, hf, array_length(hf));
1404         proto_register_subtree_array(ett, array_length(ett));
1405         expert_ssh = expert_register_protocol(proto_ssh);
1406         expert_register_field_array(expert_ssh, ei, array_length(ei));
1407
1408         ssh_module = prefs_register_protocol(proto_ssh, NULL);
1409         prefs_register_bool_preference(ssh_module, "desegment_buffers",
1410                                        "Reassemble SSH buffers spanning multiple TCP segments",
1411                                        "Whether the SSH dissector should reassemble SSH buffers spanning multiple TCP segments. "
1412                                        "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1413                                        &ssh_desegment);
1414
1415         ssh_handle = register_dissector("ssh", dissect_ssh, proto_ssh);
1416 }
1417
1418 void
1419 proto_reg_handoff_ssh(void)
1420 {
1421         dissector_add_uint("tcp.port", TCP_PORT_SSH, ssh_handle);
1422         dissector_add_uint("sctp.port", SCTP_PORT_SSH, ssh_handle);
1423         dissector_add_uint("sctp.ppi", SSH_PAYLOAD_PROTOCOL_ID, ssh_handle);
1424 }
1425
1426 /*
1427  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1428  *
1429  * Local variables:
1430  * c-basic-offset: 8
1431  * tab-width: 8
1432  * indent-tabs-mode: t
1433  * End:
1434  *
1435  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1436  * :indentSize=8:tabSize=8:noTabs=false:
1437  */