Coverage Report

Created: 2026-05-23 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libssh/src/packet.c
Line
Count
Source
1
/*
2
 * packet.c - packet building functions
3
 *
4
 * This file is part of the SSH Library
5
 *
6
 * Copyright (c) 2003-2013 by Aris Adamantiadis
7
 *
8
 * The SSH Library is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or (at your
11
 * option) any later version.
12
 *
13
 * The SSH Library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16
 * License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with the SSH Library; see the file COPYING.  If not, write to
20
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
 * MA 02111-1307, USA.
22
 */
23
24
#include "config.h"
25
26
#include <stdlib.h>
27
#include <stdio.h>
28
#include <string.h>
29
#include <errno.h>
30
31
#ifndef _WIN32
32
#include <netinet/in.h>
33
#include <arpa/inet.h>
34
#endif
35
36
#include "libssh/priv.h"
37
#include "libssh/ssh2.h"
38
#include "libssh/crypto.h"
39
#include "libssh/buffer.h"
40
#include "libssh/packet.h"
41
#include "libssh/socket.h"
42
#include "libssh/channels.h"
43
#include "libssh/misc.h"
44
#include "libssh/session.h"
45
#include "libssh/messages.h"
46
#include "libssh/pcap.h"
47
#include "libssh/kex.h"
48
#include "libssh/auth.h"
49
#include "libssh/gssapi.h"
50
#include "libssh/bytearray.h"
51
#include "libssh/dh.h"
52
53
static ssh_packet_callback default_packet_handlers[]= {
54
  ssh_packet_disconnect_callback,          // SSH2_MSG_DISCONNECT                 1
55
  ssh_packet_ignore_callback,              // SSH2_MSG_IGNORE                     2
56
  ssh_packet_unimplemented,                // SSH2_MSG_UNIMPLEMENTED              3
57
  ssh_packet_debug_callback,               // SSH2_MSG_DEBUG                      4
58
#if WITH_SERVER
59
  ssh_packet_service_request,              // SSH2_MSG_SERVICE_REQUEST            5
60
#else
61
  NULL,
62
#endif
63
  ssh_packet_service_accept,               // SSH2_MSG_SERVICE_ACCEPT             6
64
  ssh_packet_ext_info,                     // SSH2_MSG_EXT_INFO                   7
65
  NULL, NULL, NULL, NULL, NULL, NULL,
66
  NULL, NULL, NULL, NULL, NULL, NULL,      //                                     8-19
67
  ssh_packet_kexinit,                      // SSH2_MSG_KEXINIT                    20
68
  ssh_packet_newkeys,                      // SSH2_MSG_NEWKEYS                    21
69
  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
70
  NULL,                                    //                                     22-29
71
#if WITH_SERVER
72
  ssh_packet_kexdh_init,                   // SSH2_MSG_KEXDH_INIT                 30
73
                                           // SSH2_MSG_KEX_DH_GEX_REQUEST_OLD     30
74
#else
75
  NULL,
76
#endif
77
  NULL,                                    // SSH2_MSG_KEXDH_REPLY                31
78
                                           // SSH2_MSG_KEX_DH_GEX_GROUP           31
79
  NULL,                                    // SSH2_MSG_KEX_DH_GEX_INIT            32
80
  NULL,                                    // SSH2_MSG_KEX_DH_GEX_REPLY           33
81
  NULL,                                    // SSH2_MSG_KEX_DH_GEX_REQUEST         34
82
  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
83
  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
84
  NULL,                                    //                                     35-49
85
#if WITH_SERVER
86
  ssh_packet_userauth_request,             // SSH2_MSG_USERAUTH_REQUEST           50
87
#else
88
  NULL,
89
#endif
90
  ssh_packet_userauth_failure,             // SSH2_MSG_USERAUTH_FAILURE           51
91
  ssh_packet_userauth_success,             // SSH2_MSG_USERAUTH_SUCCESS           52
92
  ssh_packet_userauth_banner,              // SSH2_MSG_USERAUTH_BANNER            53
93
  NULL,NULL,NULL,NULL,NULL,NULL,           //                                     54-59
94
  ssh_packet_userauth_pk_ok,               // SSH2_MSG_USERAUTH_PK_OK             60
95
                                           // SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ  60
96
                                           // SSH2_MSG_USERAUTH_INFO_REQUEST    60
97
                                           // SSH2_MSG_USERAUTH_GSSAPI_RESPONSE   60
98
  ssh_packet_userauth_info_response,       // SSH2_MSG_USERAUTH_INFO_RESPONSE     61
99
                                           // SSH2_MSG_USERAUTH_GSSAPI_TOKEN      61
100
  NULL,                                    //                                     62
101
  NULL,                             // SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE 63
102
  NULL,                                    // SSH2_MSG_USERAUTH_GSSAPI_ERROR      64
103
  NULL,                                    // SSH2_MSG_USERAUTH_GSSAPI_ERRTOK     65
104
#if defined(WITH_GSSAPI) && defined(WITH_SERVER)
105
  ssh_packet_userauth_gssapi_mic,          // SSH2_MSG_USERAUTH_GSSAPI_MIC        66
106
#else /* WITH_GSSAPI && WITH_SERVER */
107
  NULL,
108
#endif /* WITH_GSSAPI && WITH_SERVER */
109
  NULL, NULL,
110
  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
111
  NULL, NULL, NULL, NULL,                  //                                     67-79
112
#ifdef WITH_SERVER
113
  ssh_packet_global_request,               // SSH2_MSG_GLOBAL_REQUEST             80
114
#else /* WITH_SERVER */
115
  NULL,
116
#endif /* WITH_SERVER */
117
  ssh_request_success,                     // SSH2_MSG_REQUEST_SUCCESS            81
118
  ssh_request_denied,                      // SSH2_MSG_REQUEST_FAILURE            82
119
  NULL, NULL, NULL, NULL, NULL, NULL, NULL,//                                     83-89
120
  ssh_packet_channel_open,                 // SSH2_MSG_CHANNEL_OPEN               90
121
  ssh_packet_channel_open_conf,            // SSH2_MSG_CHANNEL_OPEN_CONFIRMATION  91
122
  ssh_packet_channel_open_fail,            // SSH2_MSG_CHANNEL_OPEN_FAILURE       92
123
  channel_rcv_change_window,               // SSH2_MSG_CHANNEL_WINDOW_ADJUST      93
124
  channel_rcv_data,                        // SSH2_MSG_CHANNEL_DATA               94
125
  channel_rcv_data,                        // SSH2_MSG_CHANNEL_EXTENDED_DATA      95
126
  channel_rcv_eof,                         // SSH2_MSG_CHANNEL_EOF                96
127
  channel_rcv_close,                       // SSH2_MSG_CHANNEL_CLOSE              97
128
  channel_rcv_request,                     // SSH2_MSG_CHANNEL_REQUEST            98
129
  ssh_packet_channel_success,              // SSH2_MSG_CHANNEL_SUCCESS            99
130
  ssh_packet_channel_failure,              // SSH2_MSG_CHANNEL_FAILURE            100
131
  [SSH2_MSG_PING - 1] = ssh_packet_ping,
132
  [SSH2_MSG_PONG - 1] = ssh_packet_pong,
133
};
134
135
/** @internal
136
 * @brief check if the received packet is allowed for the current session state
137
 * @param session current ssh_session
138
 * @returns SSH_PACKET_ALLOWED if the packet is allowed; SSH_PACKET_DENIED
139
 * if the packet arrived in wrong state; SSH_PACKET_UNKNOWN if the packet type
140
 * is unknown
141
 */
142
static enum ssh_packet_filter_result_e ssh_packet_incoming_filter(ssh_session session)
143
184k
{
144
184k
    enum ssh_packet_filter_result_e rc;
145
146
#ifdef DEBUG_PACKET
147
    SSH_LOG(SSH_LOG_PACKET, "Filtering packet type %d",
148
            session->in_packet.type);
149
#endif
150
151
184k
    switch(session->in_packet.type) {
152
0
    case SSH2_MSG_DISCONNECT:                         // 1
153
        /*
154
         * States required:
155
         * - None
156
         *
157
         * Transitions:
158
         * - session->socket->state = SSH_SOCKET_CLOSED
159
         * - session->session_state = SSH_SESSION_STATE_ERROR
160
         * */
161
162
        /* Always allowed */
163
0
        rc = SSH_PACKET_ALLOWED;
164
0
        break;
165
0
    case SSH2_MSG_IGNORE:                             // 2
166
        /*
167
         * States required:
168
         * - None
169
         *
170
         * Transitions:
171
         * - None
172
         * */
173
174
        /* Always allowed */
175
0
        rc = SSH_PACKET_ALLOWED;
176
0
        break;
177
0
    case SSH2_MSG_UNIMPLEMENTED:                      // 3
178
        /*
179
         * States required:
180
         * - None
181
         *
182
         * Transitions:
183
         * - None
184
         * */
185
186
        /* Always allowed */
187
0
        rc = SSH_PACKET_ALLOWED;
188
0
        break;
189
0
    case SSH2_MSG_DEBUG:                              // 4
190
        /*
191
         * States required:
192
         * - None
193
         *
194
         * Transitions:
195
         * - None
196
         * */
197
198
        /* Always allowed */
199
0
        rc = SSH_PACKET_ALLOWED;
200
0
        break;
201
8.64k
    case SSH2_MSG_SERVICE_REQUEST:                    // 5
202
        /* Server only */
203
204
        /*
205
         * States required:
206
         * - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
207
         *   or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
208
         * - session->dh_handshake_state == DH_STATE_FINISHED
209
         *
210
         * Transitions:
211
         * - None
212
         * */
213
214
        /* If this is a client, reject the message */
215
8.64k
        if (session->client) {
216
0
            rc = SSH_PACKET_DENIED;
217
0
            break;
218
0
        }
219
220
8.64k
        if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
221
0
            (session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
222
0
        {
223
0
            rc = SSH_PACKET_DENIED;
224
0
            break;
225
0
        }
226
227
8.64k
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
228
0
            rc = SSH_PACKET_DENIED;
229
0
            break;
230
0
        }
231
232
8.64k
        rc = SSH_PACKET_ALLOWED;
233
8.64k
        break;
234
8.64k
    case SSH2_MSG_SERVICE_ACCEPT:                     // 6
235
        /*
236
         * States required:
237
         * - session->session_state == SSH_SESSION_STATE_AUTHENTICATING
238
         *   or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
239
         * - session->dh_handshake_state == DH_STATE_FINISHED
240
         * - session->auth.service_state == SSH_AUTH_SERVICE_SENT
241
         *
242
         * Transitions:
243
         * - auth.service_state = SSH_AUTH_SERVICE_ACCEPTED
244
         * */
245
246
8.64k
        if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
247
0
            (session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
248
0
        {
249
0
            rc = SSH_PACKET_DENIED;
250
0
            break;
251
0
        }
252
253
8.64k
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
254
0
            rc = SSH_PACKET_DENIED;
255
0
            break;
256
0
        }
257
258
        /* TODO check if only auth service can be requested */
259
8.64k
        if (session->auth.service_state != SSH_AUTH_SERVICE_SENT) {
260
0
            rc = SSH_PACKET_DENIED;
261
0
            break;
262
0
        }
263
264
8.64k
        rc = SSH_PACKET_ALLOWED;
265
8.64k
        break;
266
8.64k
    case SSH2_MSG_EXT_INFO:                           // 7
267
        /*
268
         * States required:
269
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
270
         *   or session->session_state == SSH_SESSION_STATE_AUTHENTICATED
271
         *   (re-exchange)
272
         * - dh_handshake_state == DH_STATE_FINISHED
273
         *
274
         * Transitions:
275
         * - None
276
         * */
277
278
8.64k
        if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATING) &&
279
0
            (session->session_state != SSH_SESSION_STATE_AUTHENTICATED))
280
0
        {
281
0
            rc = SSH_PACKET_DENIED;
282
0
            break;
283
0
        }
284
285
8.64k
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
286
0
            rc = SSH_PACKET_DENIED;
287
0
            break;
288
0
        }
289
290
8.64k
        rc = SSH_PACKET_ALLOWED;
291
8.64k
        break;
292
17.2k
    case SSH2_MSG_KEXINIT:                            // 20
293
        /*
294
         * States required:
295
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
296
         *   or session_state == SSH_SESSION_STATE_INITIAL_KEX
297
         * - dh_handshake_state == DH_STATE_INIT
298
         *   or dh_handshake_state == DH_STATE_INIT_SENT (re-exchange)
299
         *   or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
300
         *   or dh_handshake_state == DH_STATE_FINISHED (re-exchange)
301
         *
302
         * Transitions:
303
         * - session->dh_handshake_state = DH_STATE_INIT
304
         * - session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED
305
         *
306
         * On server:
307
         * - session->session_state = SSH_SESSION_STATE_DH
308
         * */
309
310
17.2k
        if ((session->session_state != SSH_SESSION_STATE_AUTHENTICATED) &&
311
17.2k
            (session->session_state != SSH_SESSION_STATE_INITIAL_KEX))
312
0
        {
313
0
            rc = SSH_PACKET_DENIED;
314
0
            break;
315
0
        }
316
317
17.2k
        if ((session->dh_handshake_state != DH_STATE_INIT) &&
318
0
            (session->dh_handshake_state != DH_STATE_INIT_SENT) &&
319
0
            (session->dh_handshake_state != DH_STATE_REQUEST_SENT) &&
320
0
            (session->dh_handshake_state != DH_STATE_FINISHED))
321
0
        {
322
0
            rc = SSH_PACKET_DENIED;
323
0
            break;
324
0
        }
325
326
17.2k
        rc = SSH_PACKET_ALLOWED;
327
17.2k
        break;
328
17.2k
    case SSH2_MSG_NEWKEYS:                            // 21
329
        /*
330
         * States required:
331
         * - session_state == SSH_SESSION_STATE_DH
332
         * - dh_handshake_state == DH_STATE_NEWKEYS_SENT
333
         *
334
         * Transitions:
335
         * - session->dh_handshake_state = DH_STATE_FINISHED
336
         * - session->session_state = SSH_SESSION_STATE_AUTHENTICATING
337
         * if session->flags & SSH_SESSION_FLAG_AUTHENTICATED
338
         * - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
339
         * */
340
341
        /* If DH has not been started, reject message */
342
17.2k
        if (session->session_state != SSH_SESSION_STATE_DH) {
343
0
            rc = SSH_PACKET_DENIED;
344
0
            break;
345
0
        }
346
347
        /* Only allowed if dh_handshake_state is in NEWKEYS_SENT state */
348
17.2k
        if (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT) {
349
0
            rc = SSH_PACKET_DENIED;
350
0
            break;
351
0
        }
352
353
17.2k
        rc = SSH_PACKET_ALLOWED;
354
17.2k
        break;
355
8.64k
    case SSH2_MSG_KEXDH_INIT:                         // 30
356
      // SSH2_MSG_KEX_ECDH_INIT:                      // 30
357
      // SSH2_MSG_KEX_HYBRID_INIT:                    // 30
358
      // SSH2_MSG_KEX_DH_GEX_REQUEST_OLD:             // 30
359
360
        /* Server only */
361
362
        /*
363
         * States required:
364
         * - session_state == SSH_SESSION_STATE_DH
365
         * - dh_handshake_state == DH_STATE_INIT
366
         *
367
         * Transitions:
368
         * - session->dh_handshake_state = DH_STATE_INIT_SENT
369
         * then calls dh_handshake_server which triggers:
370
         * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
371
         * */
372
373
8.64k
        if (session->client) {
374
0
            rc = SSH_PACKET_DENIED;
375
0
            break;
376
0
        }
377
378
8.64k
        if (session->session_state != SSH_SESSION_STATE_DH) {
379
0
            rc = SSH_PACKET_DENIED;
380
0
            break;
381
0
        }
382
383
        /* Only allowed if dh_handshake_state is in initial state */
384
8.64k
        if (session->dh_handshake_state != DH_STATE_INIT) {
385
0
            rc = SSH_PACKET_DENIED;
386
0
            break;
387
0
        }
388
389
8.64k
        rc = SSH_PACKET_ALLOWED;
390
8.64k
        break;
391
8.64k
    case SSH2_MSG_KEXDH_REPLY:                        // 31
392
      // SSH2_MSG_KEX_ECDH_REPLY:                     // 31
393
      // SSH2_MSG_KEX_HYBRID_REPLY:                   // 31
394
      // SSH2_MSG_KEX_DH_GEX_GROUP:                   // 31
395
396
        /* Client only */
397
398
        /*
399
         * States required:
400
         * - session_state == SSH_SESSION_STATE_DH
401
         * - dh_handshake_state == DH_STATE_INIT_SENT
402
         *   or dh_handshake_state == DH_STATE_REQUEST_SENT (dh-gex)
403
         *
404
         * Transitions:
405
         * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
406
         * */
407
408
8.64k
        if (session->server) {
409
0
            rc = SSH_PACKET_DENIED;
410
0
            break;
411
0
        }
412
413
8.64k
        if (session->session_state != SSH_SESSION_STATE_DH) {
414
0
            rc = SSH_PACKET_DENIED;
415
0
            break;
416
0
        }
417
418
8.64k
        if (session->dh_handshake_state != DH_STATE_INIT_SENT &&
419
0
            session->dh_handshake_state != DH_STATE_REQUEST_SENT) {
420
0
            rc = SSH_PACKET_DENIED;
421
0
            break;
422
0
        }
423
424
8.64k
        rc = SSH_PACKET_ALLOWED;
425
8.64k
        break;
426
0
    case SSH2_MSG_KEX_DH_GEX_INIT:                    // 32
427
      // SSH2_MSG_KEXGSS_COMPLETE:                    // 32
428
0
        if (ssh_kex_is_gss(session->next_crypto)) {
429
            /* SSH2_MSG_KEXGSS_COMPLETE */
430
            /* Client only */
431
432
            /*
433
             * States required:
434
             * - session_state == SSH_SESSION_STATE_DH
435
             * - dh_handshake_state == DH_STATE_INIT_SENT
436
             *
437
             * Transitions:
438
             * - session->dh_handshake_state = DH_STATE_INIT_SENT
439
             * then calls ssh_packet_client_gss_kex_reply which triggers:
440
             * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
441
             * */
442
443
0
            if (!session->client) {
444
0
                rc = SSH_PACKET_DENIED;
445
0
                break;
446
0
            }
447
448
0
            if (session->session_state != SSH_SESSION_STATE_DH) {
449
0
                rc = SSH_PACKET_DENIED;
450
0
                break;
451
0
            }
452
453
0
            if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
454
0
                rc = SSH_PACKET_DENIED;
455
0
                break;
456
0
            }
457
0
        } else {
458
            /* SSH2_MSG_KEX_DH_GEX_INIT */
459
            /* Server only */
460
461
            /*
462
             * States required:
463
             * - session_state == SSH_SESSION_STATE_DH
464
             * - dh_handshake_state == DH_STATE_GROUP_SENT
465
             *
466
             * Transitions:
467
             * - session->dh_handshake_state = DH_STATE_GROUP_SENT
468
             * then calls ssh_packet_server_dhgex_init which triggers:
469
             * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
470
             * */
471
472
0
            if (session->client) {
473
0
                rc = SSH_PACKET_DENIED;
474
0
                break;
475
0
            }
476
477
0
            if (session->session_state != SSH_SESSION_STATE_DH) {
478
0
                rc = SSH_PACKET_DENIED;
479
0
                break;
480
0
            }
481
482
            /* Only allowed if dh_handshake_state is in initial state */
483
0
            if (session->dh_handshake_state != DH_STATE_GROUP_SENT) {
484
0
                rc = SSH_PACKET_DENIED;
485
0
                break;
486
0
            }
487
0
        }
488
0
        rc = SSH_PACKET_ALLOWED;
489
0
        break;
490
0
    case SSH2_MSG_KEX_DH_GEX_REPLY:                   // 33
491
492
        /* Client only */
493
494
        /*
495
         * States required:
496
         * - session_state == SSH_SESSION_STATE_DH
497
         * - dh_handshake_state == DH_STATE_INIT_SENT
498
         *
499
         * Transitions:
500
         * - session->dh_handshake_state = DH_STATE_NEWKEYS_SENT
501
         * */
502
503
0
        if (session->server) {
504
0
            rc = SSH_PACKET_DENIED;
505
0
            break;
506
0
        }
507
508
0
        if (session->session_state != SSH_SESSION_STATE_DH) {
509
0
            rc = SSH_PACKET_DENIED;
510
0
            break;
511
0
        }
512
513
0
        if (session->dh_handshake_state != DH_STATE_INIT_SENT) {
514
0
            rc = SSH_PACKET_DENIED;
515
0
            break;
516
0
        }
517
518
0
        rc = SSH_PACKET_ALLOWED;
519
0
        break;
520
0
    case SSH2_MSG_KEX_DH_GEX_REQUEST:                 // 34
521
522
        /* Server only */
523
524
        /*
525
         * States required:
526
         * - session_state == SSH_SESSION_STATE_DH
527
         * - dh_handshake_state == DH_STATE_INIT
528
         *
529
         * Transitions:
530
         * - session->dh_handshake_state = DH_STATE_INIT_SENT
531
         * then calls ssh_packet_server_dhgex_request which triggers:
532
         * - session->dh_handshake_state = DH_STATE_GROUP_SENT
533
         * */
534
535
0
        if (session->client) {
536
0
            rc = SSH_PACKET_DENIED;
537
0
            break;
538
0
        }
539
540
0
        if (session->session_state != SSH_SESSION_STATE_DH) {
541
0
            rc = SSH_PACKET_DENIED;
542
0
            break;
543
0
        }
544
545
        /* Only allowed if dh_handshake_state is in initial state */
546
0
        if (session->dh_handshake_state != DH_STATE_INIT) {
547
0
            rc = SSH_PACKET_DENIED;
548
0
            break;
549
0
        }
550
551
0
        rc = SSH_PACKET_ALLOWED;
552
0
        break;
553
8.64k
    case SSH2_MSG_USERAUTH_REQUEST:                   // 50
554
        /* Server only */
555
556
        /*
557
         * States required:
558
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
559
         * - dh_handshake_state == DH_STATE_FINISHED
560
         *
561
         * Transitions:
562
         * - if authentication was successful:
563
         *   - session_state = SSH_SESSION_STATE_AUTHENTICATED
564
         * */
565
566
        /* If this is a client, reject the message */
567
8.64k
        if (session->client) {
568
0
            rc = SSH_PACKET_DENIED;
569
0
            break;
570
0
        }
571
572
8.64k
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
573
0
            rc = SSH_PACKET_DENIED;
574
0
            break;
575
0
        }
576
577
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
578
0
            rc = SSH_PACKET_DENIED;
579
0
            break;
580
0
        }
581
582
8.64k
        rc = SSH_PACKET_ALLOWED;
583
8.64k
        break;
584
0
    case SSH2_MSG_USERAUTH_FAILURE:                   // 51
585
        /*
586
         * States required:
587
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
588
         * - dh_handshake_state == DH_STATE_FINISHED
589
         * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
590
         *   or session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
591
         *   or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
592
         *   or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
593
         *   or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
594
         *
595
         * Transitions:
596
         * - if unpacking failed:
597
         *   - session->auth.state = SSH_AUTH_ERROR
598
         * - if failure was partial:
599
         *   - session->auth.state = SSH_AUTH_PARTIAL
600
         * - else:
601
         *   - session->auth.state = SSH_AUTH_STATE_FAILED
602
         * */
603
604
        /* If this is a server, reject the message */
605
0
        if (session->server) {
606
0
            rc = SSH_PACKET_DENIED;
607
0
            break;
608
0
        }
609
610
0
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
611
0
            rc = SSH_PACKET_DENIED;
612
0
            break;
613
0
        }
614
615
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
616
0
            rc = SSH_PACKET_DENIED;
617
0
            break;
618
0
        }
619
620
0
        rc = SSH_PACKET_ALLOWED;
621
0
        break;
622
8.64k
    case SSH2_MSG_USERAUTH_SUCCESS:                   // 52
623
        /*
624
         * States required:
625
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
626
         * - dh_handshake_state == DH_STATE_FINISHED
627
         * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
628
         *   or session->auth.state == SSH_AUTH_STATE_PUBKEY_AUTH_SENT
629
         *   or session->auth.state == SSH_AUTH_STATE_PASSWORD_AUTH_SENT
630
         *   or session->auth.state == SSH_AUTH_STATE_GSSAPI_MIC_SENT
631
         *   or session->auth.state == SSH_AUTH_STATE_GSSAPI_KEYEX_MIC_SENT
632
         *   or session->auth.state == SSH_AUTH_STATE_AUTH_NONE_SENT
633
         *
634
         * Transitions:
635
         * - session->auth.state = SSH_AUTH_STATE_SUCCESS
636
         * - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
637
         * - session->flags |= SSH_SESSION_FLAG_AUTHENTICATED
638
         * - sessions->auth.current_method = SSH_AUTH_METHOD_UNKNOWN
639
         * */
640
641
        /* If this is a server, reject the message */
642
8.64k
        if (session->server) {
643
0
            rc = SSH_PACKET_DENIED;
644
0
            break;
645
0
        }
646
647
8.64k
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
648
0
            rc = SSH_PACKET_DENIED;
649
0
            break;
650
0
        }
651
652
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
653
0
            rc = SSH_PACKET_DENIED;
654
0
            break;
655
0
        }
656
657
8.64k
        if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
658
8.64k
            (session->auth.state != SSH_AUTH_STATE_PUBKEY_AUTH_SENT) &&
659
8.64k
            (session->auth.state != SSH_AUTH_STATE_PASSWORD_AUTH_SENT) &&
660
8.64k
            (session->auth.state != SSH_AUTH_STATE_GSSAPI_MIC_SENT) &&
661
8.64k
            (session->auth.state != SSH_AUTH_STATE_GSSAPI_KEYEX_MIC_SENT) &&
662
8.64k
            (session->auth.state != SSH_AUTH_STATE_AUTH_NONE_SENT)) {
663
0
            rc = SSH_PACKET_DENIED;
664
0
            break;
665
0
        }
666
667
8.64k
        rc = SSH_PACKET_ALLOWED;
668
8.64k
        break;
669
0
    case SSH2_MSG_USERAUTH_BANNER:                    // 53
670
        /*
671
         * States required:
672
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
673
         *
674
         * Transitions:
675
         * - None
676
         * */
677
678
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
679
0
            rc = SSH_PACKET_DENIED;
680
0
            break;
681
0
        }
682
683
0
        rc = SSH_PACKET_ALLOWED;
684
0
        break;
685
0
    case SSH2_MSG_USERAUTH_PK_OK:                     // 60
686
      // SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ:          // 60
687
      // SSH2_MSG_USERAUTH_INFO_REQUEST:              // 60
688
      // SSH2_MSG_USERAUTH_GSSAPI_RESPONSE:           // 60
689
690
        /*
691
         * States required:
692
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
693
         * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
694
         *   or
695
         *   session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
696
         *   or
697
         *   session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
698
         *
699
         * Transitions:
700
         * Depending on the current state, the message is treated
701
         * differently:
702
         * - session->auth.state == SSH_AUTH_STATE_KBDINT_SENT
703
         *   - session->auth.state = SSH_AUTH_STATE_INFO
704
         * - session->auth.state == SSH_AUTH_STATE_GSSAPI_REQUEST_SENT
705
         *   - session->auth.state = SSH_AUTH_STATE_GSSAPI_TOKEN
706
         * - session->auth.state == SSH_AUTH_STATE_PUBKEY_OFFER_SENT
707
         *   - session->auth.state = SSH_AUTH_STATE_PK_OK
708
         * */
709
710
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
711
0
            rc = SSH_PACKET_DENIED;
712
0
            break;
713
0
        }
714
715
0
        if ((session->auth.state != SSH_AUTH_STATE_KBDINT_SENT) &&
716
0
            (session->auth.state != SSH_AUTH_STATE_PUBKEY_OFFER_SENT) &&
717
0
            (session->auth.state != SSH_AUTH_STATE_GSSAPI_REQUEST_SENT))
718
0
        {
719
0
            rc = SSH_PACKET_DENIED;
720
0
            break;
721
0
        }
722
723
0
        rc = SSH_PACKET_ALLOWED;
724
0
        break;
725
0
    case SSH2_MSG_USERAUTH_INFO_RESPONSE:             // 61
726
      // SSH2_MSG_USERAUTH_GSSAPI_TOKEN:              // 61
727
728
        /*
729
         * States required:
730
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
731
         * - session_state->auth.state == SSH_SESSION_STATE_GSSAPI_TOKEN
732
         *   or
733
         *   session_state->auth.state == SSH_SESSION_STATE_INFO
734
         *
735
         * Transitions:
736
         * - None
737
         * */
738
739
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
740
0
            rc = SSH_PACKET_DENIED;
741
0
            break;
742
0
        }
743
744
0
        if ((session->auth.state != SSH_AUTH_STATE_INFO) &&
745
0
            (session->auth.state != SSH_AUTH_STATE_GSSAPI_TOKEN))
746
0
        {
747
0
            rc = SSH_PACKET_DENIED;
748
0
            break;
749
0
        }
750
751
0
        rc = SSH_PACKET_ALLOWED;
752
0
        break;
753
0
    case SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE:  // 63
754
        /* Server only */
755
        /*
756
         * States required:
757
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
758
         * - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC
759
         *
760
         * Transitions:
761
         * - None
762
         */
763
#ifdef WITH_GSSAPI
764
        if (session->client) {
765
            rc = SSH_PACKET_DENIED;
766
            break;
767
        }
768
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
769
            rc = SSH_PACKET_DENIED;
770
            break;
771
        }
772
        if (session->gssapi == NULL) {
773
            rc = SSH_PACKET_DENIED;
774
            break;
775
        }
776
        if (session->gssapi->state != SSH_GSSAPI_STATE_RCV_MIC) {
777
            rc = SSH_PACKET_DENIED;
778
            break;
779
        }
780
        rc = SSH_PACKET_ALLOWED;
781
        break;
782
#else
783
0
        rc = SSH_PACKET_DENIED;
784
0
        break;
785
0
#endif  /* WITH_GSSAPI */
786
0
    case SSH2_MSG_USERAUTH_GSSAPI_ERROR:              // 64
787
        /* Client only */
788
        /*
789
         * States required:
790
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
791
         *
792
         * Transitions:
793
         * - None
794
         */
795
#ifdef WITH_GSSAPI
796
        if (session->server) {
797
            rc = SSH_PACKET_DENIED;
798
            break;
799
        }
800
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
801
            rc = SSH_PACKET_DENIED;
802
            break;
803
        }
804
805
        rc = SSH_PACKET_ALLOWED;
806
        break;
807
#else
808
0
        rc = SSH_PACKET_DENIED;
809
0
        break;
810
0
#endif  /* WITH_GSSAPI */
811
0
    case SSH2_MSG_USERAUTH_GSSAPI_ERRTOK:             // 65
812
        /*
813
         * States required:
814
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
815
         *
816
         * Transitions:
817
         * - None
818
         */
819
#ifdef WITH_GSSAPI
820
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
821
            rc = SSH_PACKET_DENIED;
822
            break;
823
        }
824
825
        rc = SSH_PACKET_ALLOWED;
826
        break;
827
#else
828
0
        rc = SSH_PACKET_DENIED;
829
0
        break;
830
0
#endif  /* WITH_GSSAPI */
831
0
    case SSH2_MSG_USERAUTH_GSSAPI_MIC:                // 66
832
        /* Server only */
833
834
        /*
835
         * States required:
836
         * - session_state == SSH_SESSION_STATE_AUTHENTICATING
837
         * - session->gssapi->state == SSH_GSSAPI_STATE_RCV_MIC
838
         *
839
         * Transitions:
840
         * Depending on the result of the verification, the states are
841
         * changed:
842
         * - SSH_AUTH_SUCCESS:
843
         *   - session->session_state = SSH_SESSION_STATE_AUTHENTICATED
844
         *   - session->flags != SSH_SESSION_FLAG_AUTHENTICATED
845
         * - SSH_AUTH_PARTIAL:
846
         *   - None
847
         * - any other case:
848
         *   - None
849
         * */
850
#ifdef WITH_GSSAPI
851
        /* If this is a client, reject the message */
852
        if (session->client) {
853
            rc = SSH_PACKET_DENIED;
854
            break;
855
        }
856
857
        if (session->dh_handshake_state != DH_STATE_FINISHED) {
858
            rc = SSH_PACKET_DENIED;
859
            break;
860
        }
861
862
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATING) {
863
            rc = SSH_PACKET_DENIED;
864
            break;
865
        }
866
867
        rc = SSH_PACKET_ALLOWED;
868
        break;
869
#else
870
0
        rc = SSH_PACKET_DENIED;
871
0
        break;
872
0
#endif  /* WITH_GSSAPI */
873
0
    case SSH2_MSG_GLOBAL_REQUEST:                     // 80
874
        /*
875
         * States required:
876
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
877
         *
878
         * Transitions:
879
         * - None
880
         * */
881
882
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
883
0
            rc = SSH_PACKET_DENIED;
884
0
            break;
885
0
        }
886
887
0
        rc = SSH_PACKET_ALLOWED;
888
0
        break;
889
0
    case SSH2_MSG_REQUEST_SUCCESS:                    // 81
890
        /*
891
         * States required:
892
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
893
         *
894
         * Transitions:
895
         * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
896
         * - To   channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
897
         *
898
         * If not in a pending state, message is ignored in the callback handler.
899
         * */
900
901
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
902
0
            rc = SSH_PACKET_DENIED;
903
0
            break;
904
0
        }
905
906
0
        rc = SSH_PACKET_ALLOWED;
907
0
        break;
908
0
    case SSH2_MSG_REQUEST_FAILURE:                    // 82
909
        /*
910
         * States required:
911
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
912
         *
913
         * Transitions:
914
         * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
915
         * - To   channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
916
         *
917
         * If not in a pending state, message is ignored in the callback handler.
918
         * */
919
920
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
921
0
            rc = SSH_PACKET_DENIED;
922
0
            break;
923
0
        }
924
925
0
        rc = SSH_PACKET_ALLOWED;
926
0
        break;
927
8.64k
    case SSH2_MSG_CHANNEL_OPEN:                       // 90
928
        /*
929
         * States required:
930
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
931
         *
932
         * Transitions:
933
         * - None
934
         * */
935
936
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
937
0
            rc = SSH_PACKET_DENIED;
938
0
            break;
939
0
        }
940
941
8.64k
        rc = SSH_PACKET_ALLOWED;
942
8.64k
        break;
943
8.64k
    case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:          // 91
944
        /*
945
         * States required:
946
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
947
         *
948
         * Transitions:
949
         * - channel->state = SSH_CHANNEL_STATE_OPEN
950
         * - channel->flags &= ~SSH_CHANNEL_FLAG_NOT_BOUND
951
         * */
952
953
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
954
0
            rc = SSH_PACKET_DENIED;
955
0
            break;
956
0
        }
957
958
8.64k
        rc = SSH_PACKET_ALLOWED;
959
8.64k
        break;
960
0
    case SSH2_MSG_CHANNEL_OPEN_FAILURE:               // 92
961
        /*
962
         * States required:
963
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
964
         *
965
         * Transitions:
966
         * - channel->state = SSH_CHANNEL_STATE_OPEN_DENIED
967
         * */
968
969
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
970
0
            rc = SSH_PACKET_DENIED;
971
0
            break;
972
0
        }
973
974
0
        rc = SSH_PACKET_ALLOWED;
975
0
        break;
976
0
    case SSH2_MSG_CHANNEL_WINDOW_ADJUST:              // 93
977
        /*
978
         * States required:
979
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
980
         *
981
         * Transitions:
982
         * - None
983
         * */
984
985
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
986
0
            rc = SSH_PACKET_DENIED;
987
0
            break;
988
0
        }
989
990
0
        rc = SSH_PACKET_ALLOWED;
991
0
        break;
992
46.0k
    case SSH2_MSG_CHANNEL_DATA:                       // 94
993
        /*
994
         * States required:
995
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
996
         *
997
         * Transitions:
998
         * - None
999
         * */
1000
1001
46.0k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1002
0
            rc = SSH_PACKET_DENIED;
1003
0
            break;
1004
0
        }
1005
1006
46.0k
        rc = SSH_PACKET_ALLOWED;
1007
46.0k
        break;
1008
0
    case SSH2_MSG_CHANNEL_EXTENDED_DATA:              // 95
1009
        /*
1010
         * States required:
1011
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1012
         *
1013
         * Transitions:
1014
         * - None
1015
         * */
1016
1017
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1018
0
            rc = SSH_PACKET_DENIED;
1019
0
            break;
1020
0
        }
1021
1022
0
        rc = SSH_PACKET_ALLOWED;
1023
0
        break;
1024
8.64k
    case SSH2_MSG_CHANNEL_EOF:                        // 96
1025
        /*
1026
         * States required:
1027
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1028
         *
1029
         * Transitions:
1030
         * - None
1031
         * */
1032
1033
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1034
0
            rc = SSH_PACKET_DENIED;
1035
0
            break;
1036
0
        }
1037
1038
8.64k
        rc = SSH_PACKET_ALLOWED;
1039
8.64k
        break;
1040
8.64k
    case SSH2_MSG_CHANNEL_CLOSE:                      // 97
1041
        /*
1042
         * States required:
1043
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1044
         *
1045
         * Transitions:
1046
         * - channel->state = SSH_CHANNEL_STATE_CLOSED
1047
         * - channel->flags |= SSH_CHANNEL_FLAG_CLOSED_REMOTE
1048
         * */
1049
1050
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1051
0
            rc = SSH_PACKET_DENIED;
1052
0
            break;
1053
0
        }
1054
1055
8.64k
        rc = SSH_PACKET_ALLOWED;
1056
8.64k
        break;
1057
8.64k
    case SSH2_MSG_CHANNEL_REQUEST:                    // 98
1058
        /*
1059
         * States required:
1060
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1061
         *
1062
         * Transitions:
1063
         * - Depends on the request
1064
         * */
1065
1066
8.64k
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1067
0
            rc = SSH_PACKET_DENIED;
1068
0
            break;
1069
0
        }
1070
1071
8.64k
        rc = SSH_PACKET_ALLOWED;
1072
8.64k
        break;
1073
2
    case SSH2_MSG_CHANNEL_SUCCESS:                    // 99
1074
        /*
1075
         * States required:
1076
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1077
         *
1078
         * Transitions:
1079
         * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
1080
         * - To   channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
1081
         *
1082
         * If not in a pending state, message is ignored in the callback handler.
1083
         * */
1084
1085
2
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1086
0
            rc = SSH_PACKET_DENIED;
1087
0
            break;
1088
0
        }
1089
1090
2
        rc = SSH_PACKET_ALLOWED;
1091
2
        break;
1092
0
    case SSH2_MSG_CHANNEL_FAILURE:                    // 100
1093
        /*
1094
         * States required:
1095
         * - session_state == SSH_SESSION_STATE_AUTHENTICATED
1096
         *
1097
         * Transitions:
1098
         * - From channel->request_state == SSH_CHANNEL_REQ_STATE_PENDING
1099
         * - To   channel->request_state = SSH_CHANNEL_REQ_STATE_ACCEPTED
1100
         *
1101
         * If not in a pending state, message is ignored in the callback handler.
1102
         * */
1103
1104
0
        if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED) {
1105
0
            rc = SSH_PACKET_DENIED;
1106
0
            break;
1107
0
        }
1108
1109
0
        rc = SSH_PACKET_ALLOWED;
1110
0
        break;
1111
0
    case SSH2_MSG_PING: // 192
1112
0
    case SSH2_MSG_PONG: // 193
1113
        /*
1114
         * Transport-level ping/pong messages.
1115
         *
1116
         * Always allow PING and PONG messages through the filter.
1117
         * State checking (auth/rekey) is handled in the packet handler itself,
1118
         * following OpenSSH's approach of treating these as implicit
1119
         * transport-level messages (like IGNORE and DEBUG).
1120
         *
1121
         * States required:
1122
         * - None (always allowed)
1123
         *
1124
         * Transitions:
1125
         * - None
1126
         */
1127
0
        rc = SSH_PACKET_ALLOWED;
1128
0
        break;
1129
0
    default:
1130
        /* Unknown message, do not filter */
1131
0
        rc = SSH_PACKET_UNKNOWN;
1132
0
        goto end;
1133
184k
    }
1134
1135
184k
end:
1136
#ifdef DEBUG_PACKET
1137
    if (rc == SSH_PACKET_DENIED) {
1138
        SSH_LOG(SSH_LOG_PACKET, "REJECTED packet type %d: ",
1139
                session->in_packet.type);
1140
    }
1141
1142
    if (rc == SSH_PACKET_UNKNOWN) {
1143
        SSH_LOG(SSH_LOG_PACKET, "UNKNOWN packet type %d",
1144
                session->in_packet.type);
1145
    }
1146
#endif
1147
1148
184k
    return rc;
1149
184k
}
1150
1151
/* Returns current_crypto structure from the session.
1152
 * During key exchange (or rekey), after one of the sides
1153
 * sending NEWKEYS packet, this might return next_crypto for one
1154
 * of the directions that is ahead to send already queued packets
1155
 */
1156
struct ssh_crypto_struct *
1157
ssh_packet_get_current_crypto(ssh_session session,
1158
                              enum ssh_crypto_direction_e direction)
1159
1.84M
{
1160
1.84M
    struct ssh_crypto_struct *crypto = NULL;
1161
1162
1.84M
    if (session == NULL) {
1163
0
        return NULL;
1164
0
    }
1165
1166
1.84M
    if (session->current_crypto != NULL &&
1167
1.59M
        session->current_crypto->used & direction) {
1168
1.59M
        crypto = session->current_crypto;
1169
1.59M
    } else if (session->next_crypto != NULL &&
1170
248k
               session->next_crypto->used & direction) {
1171
0
        crypto = session->next_crypto;
1172
248k
    } else {
1173
248k
        return NULL;
1174
248k
    }
1175
1176
1.59M
    switch (direction) {
1177
1.03M
    case SSH_DIRECTION_IN:
1178
1.03M
        if (crypto->in_cipher != NULL) {
1179
1.03M
            return crypto;
1180
1.03M
        }
1181
18.4E
        break;
1182
18.4E
    case SSH_DIRECTION_OUT:
1183
334k
        if (crypto->out_cipher != NULL) {
1184
334k
            return crypto;
1185
334k
        }
1186
0
        break;
1187
221k
    case SSH_DIRECTION_BOTH:
1188
221k
        if (crypto->in_cipher != NULL &&
1189
221k
            crypto->out_cipher != NULL) {
1190
221k
            return crypto;
1191
221k
        }
1192
1.59M
    }
1193
1194
0
    return NULL;
1195
1.59M
}
1196
1197
665k
#define MAX_PACKETS    (1UL<<31)
1198
1199
static bool ssh_packet_need_rekey(ssh_session session,
1200
                                  const uint32_t payloadsize)
1201
394k
{
1202
394k
    bool data_rekey_needed = false;
1203
394k
    struct ssh_crypto_struct *crypto = NULL;
1204
394k
    struct ssh_cipher_struct *out_cipher = NULL, *in_cipher = NULL;
1205
394k
    uint32_t next_blocks;
1206
1207
    /* We can safely rekey only in authenticated state */
1208
394k
    if ((session->flags & SSH_SESSION_FLAG_AUTHENTICATED) == 0) {
1209
172k
        return false;
1210
172k
    }
1211
1212
    /* Do not rekey if the rekey/key-exchange is in progress */
1213
221k
    if (session->dh_handshake_state != DH_STATE_FINISHED) {
1214
0
        return false;
1215
0
    }
1216
1217
221k
    crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_BOTH);
1218
221k
    if (crypto == NULL) {
1219
0
        return false;
1220
0
    }
1221
1222
221k
    out_cipher = crypto->out_cipher;
1223
221k
    in_cipher = crypto->in_cipher;
1224
1225
    /* Make sure we can send at least something for very small limits */
1226
221k
    if ((out_cipher->packets == 0) && (in_cipher->packets == 0)) {
1227
0
        return false;
1228
0
    }
1229
1230
    /* Time based rekeying */
1231
221k
    if (session->opts.rekey_time != 0 &&
1232
0
        ssh_timeout_elapsed(&session->last_rekey_time,
1233
0
                            session->opts.rekey_time)) {
1234
0
        return true;
1235
0
    }
1236
1237
    /* RFC4344, Section 3.1 Recommends rekeying after 2^31 packets in either
1238
     * direction to avoid possible information leakage through the MAC tag
1239
     */
1240
221k
    if (out_cipher->packets > MAX_PACKETS ||
1241
221k
        in_cipher->packets > MAX_PACKETS) {
1242
0
        return true;
1243
0
    }
1244
1245
    /* Data-based rekeying:
1246
     *  * For outgoing packets we can still delay them
1247
     *  * Incoming packets need to be processed anyway, but we can
1248
     *    signalize our intention to rekey
1249
     */
1250
221k
    next_blocks = payloadsize / out_cipher->blocksize;
1251
221k
    data_rekey_needed = (out_cipher->max_blocks != 0 &&
1252
221k
                         out_cipher->blocks + next_blocks > out_cipher->max_blocks) ||
1253
221k
                         (in_cipher->max_blocks != 0 &&
1254
221k
                         in_cipher->blocks + next_blocks > in_cipher->max_blocks);
1255
1256
221k
    SSH_LOG(SSH_LOG_PACKET,
1257
221k
            "rekey: [data_rekey_needed=%d, out_blocks=%" PRIu64 ", in_blocks=%" PRIu64 "]",
1258
221k
            data_rekey_needed,
1259
221k
            out_cipher->blocks + next_blocks,
1260
221k
            in_cipher->blocks + next_blocks);
1261
1262
221k
    return data_rekey_needed;
1263
221k
}
1264
1265
/* in nonblocking mode, socket_read will read as much as it can, and return */
1266
/* SSH_OK if it has read at least len bytes, otherwise, SSH_AGAIN. */
1267
/* in blocking mode, it will read at least len bytes and will block until it's ok. */
1268
1269
/** @internal
1270
 * @brief handles a data received event
1271
 *
1272
 * Processes up to one packet from the given buffer and calls the handlers
1273
 * for the different packet types or an exception handler callback. If the
1274
 * buffer does not contain a complete packet, nothing is processed and zero
1275
 * is returned. So typically this function needs to be called in a loop until
1276
 * it returns zero to properly handle multiple packets in the buffer.
1277
 *
1278
 * @param user pointer to current ssh_session
1279
 * @param data pointer to the data received
1280
 * @len length of data received. It might not be enough for a complete packet
1281
 * @returns number of bytes read and processed. Zero means only partial packet
1282
 * received.
1283
 */
1284
size_t
1285
ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
1286
649k
{
1287
649k
    ssh_session session = (ssh_session)user;
1288
649k
    uint32_t blocksize = 8;
1289
649k
    uint32_t lenfield_blocksize = 8;
1290
649k
    size_t current_macsize = 0;
1291
649k
    uint8_t *ptr = NULL;
1292
649k
    ssize_t to_be_read;
1293
649k
    int rc;
1294
649k
    uint8_t *cleartext_packet = NULL;
1295
649k
    uint8_t *packet_second_block = NULL;
1296
649k
    uint8_t *mac = NULL;
1297
649k
    size_t packet_remaining, packet_offset;
1298
649k
    uint32_t packet_len, compsize, payloadsize;
1299
649k
    uint8_t padding;
1300
649k
    size_t processed = 0; /* number of bytes processed from the callback */
1301
649k
    enum ssh_packet_filter_result_e filter_result;
1302
649k
    struct ssh_crypto_struct *crypto = NULL;
1303
649k
    bool etm = false;
1304
649k
    uint32_t etm_packet_offset = 0;
1305
649k
    bool ok;
1306
1307
649k
    crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
1308
649k
    if (crypto != NULL) {
1309
556k
        current_macsize = hmac_digest_len(crypto->in_hmac);
1310
556k
        blocksize = crypto->in_cipher->blocksize;
1311
556k
        lenfield_blocksize = crypto->in_cipher->lenfield_blocksize;
1312
556k
        etm = crypto->in_hmac_etm;
1313
556k
    }
1314
1315
649k
    if (etm) {
1316
        /* In EtM mode packet size is unencrypted. This means
1317
         * we need to use this offset and set the block size
1318
         * that is part of the encrypted part to 0.
1319
         */
1320
0
        etm_packet_offset = sizeof(uint32_t);
1321
0
        lenfield_blocksize = 0;
1322
649k
    } else if (lenfield_blocksize == 0) {
1323
556k
        lenfield_blocksize = blocksize;
1324
556k
    }
1325
649k
    if (data == NULL) {
1326
0
        goto error;
1327
0
    }
1328
1329
649k
    if (session->session_state == SSH_SESSION_STATE_ERROR) {
1330
0
        goto error;
1331
0
    }
1332
#ifdef DEBUG_PACKET
1333
    SSH_LOG(SSH_LOG_PACKET,
1334
            "rcv packet cb (len=%zu, state=%s)",
1335
            receivedlen,
1336
            session->packet_state == PACKET_STATE_INIT ?
1337
                "INIT" :
1338
                session->packet_state == PACKET_STATE_SIZEREAD ?
1339
                    "SIZE_READ" :
1340
                    session->packet_state == PACKET_STATE_PROCESSING ?
1341
                    "PROCESSING" : "unknown");
1342
#endif
1343
649k
    switch (session->packet_state) {
1344
328k
        case PACKET_STATE_INIT:
1345
328k
            if (receivedlen < lenfield_blocksize + etm_packet_offset) {
1346
                /*
1347
                 * We didn't receive enough data to read either at least one
1348
                 * block size or the unencrypted length in EtM mode.
1349
                 */
1350
#ifdef DEBUG_PACKET
1351
                SSH_LOG(SSH_LOG_PACKET,
1352
                        "Waiting for more data (%zu < %u)",
1353
                        receivedlen,
1354
                        lenfield_blocksize);
1355
#endif
1356
144k
                return 0;
1357
144k
            }
1358
1359
184k
            session->in_packet = (struct packet_struct) {
1360
184k
                .type = 0,
1361
184k
            };
1362
1363
184k
            if (session->in_buffer) {
1364
184k
                rc = ssh_buffer_reinit(session->in_buffer);
1365
184k
                if (rc < 0) {
1366
0
                    goto error;
1367
0
                }
1368
18.4E
            } else {
1369
18.4E
                session->in_buffer = ssh_buffer_new();
1370
18.4E
                if (session->in_buffer == NULL) {
1371
0
                    goto error;
1372
0
                }
1373
18.4E
            }
1374
1375
184k
            if (!etm) {
1376
184k
                ptr = ssh_buffer_allocate(session->in_buffer,
1377
184k
                                          lenfield_blocksize);
1378
184k
                if (ptr == NULL) {
1379
0
                    goto error;
1380
0
                }
1381
184k
                packet_len = ssh_packet_decrypt_len(session, ptr,
1382
184k
                                                    (uint8_t *)data);
1383
184k
                to_be_read = packet_len - lenfield_blocksize + sizeof(uint32_t);
1384
184k
            } else {
1385
                /* Length is unencrypted in case of Encrypt-then-MAC */
1386
1
                packet_len = PULL_BE_U32(data, 0);
1387
1
                to_be_read = packet_len - etm_packet_offset;
1388
1
            }
1389
1390
184k
            processed += lenfield_blocksize + etm_packet_offset;
1391
184k
            if (packet_len > MAX_PACKET_LEN) {
1392
0
                ssh_set_error(session,
1393
0
                              SSH_FATAL,
1394
0
                              "read_packet(): Packet len too high(%" PRIu32 " %.4" PRIx32 ")",
1395
0
                              packet_len, packet_len);
1396
0
                goto error;
1397
0
            }
1398
184k
            if (to_be_read < 0) {
1399
                /* remote sshd sends invalid sizes? */
1400
0
                ssh_set_error(session,
1401
0
                              SSH_FATAL,
1402
0
                              "Given numbers of bytes left to be read < 0 (%zd)!",
1403
0
                              to_be_read);
1404
0
                goto error;
1405
0
            }
1406
1407
184k
            session->in_packet.len = packet_len;
1408
184k
            session->packet_state = PACKET_STATE_SIZEREAD;
1409
184k
            FALL_THROUGH;
1410
504k
        case PACKET_STATE_SIZEREAD:
1411
504k
            packet_len = session->in_packet.len;
1412
504k
            packet_offset = processed = lenfield_blocksize + etm_packet_offset;
1413
504k
            to_be_read = packet_len + sizeof(uint32_t) + current_macsize;
1414
            /* if to_be_read is zero, the whole packet was blocksize bytes. */
1415
504k
            if (to_be_read != 0) {
1416
504k
                if (receivedlen < (unsigned long)to_be_read) {
1417
                    /* give up, not enough data in buffer */
1418
320k
                    SSH_LOG(SSH_LOG_PACKET,
1419
320k
                            "packet: partial packet (read len) "
1420
320k
                            "[len=%" PRIu32 ", receivedlen=%zu, to_be_read=%zd]",
1421
320k
                            packet_len,
1422
320k
                            receivedlen,
1423
320k
                            to_be_read);
1424
320k
                    return 0;
1425
320k
                }
1426
1427
184k
                packet_second_block = (uint8_t*)data + packet_offset;
1428
184k
                processed = to_be_read - current_macsize;
1429
184k
            }
1430
1431
184k
            if (packet_offset - sizeof(uint32_t) > (size_t)packet_len) {
1432
0
                ssh_set_error(session,
1433
0
                              SSH_FATAL,
1434
0
                              "Invalid packet length %" PRIu32 ", required %zu",
1435
0
                              packet_len,
1436
0
                              packet_offset + sizeof(uint32_t));
1437
0
                goto error;
1438
0
            }
1439
1440
            /* remaining encrypted bytes from the packet, MAC not included */
1441
184k
            packet_remaining = packet_len - (packet_offset - sizeof(uint32_t));
1442
184k
            cleartext_packet = ssh_buffer_allocate(session->in_buffer,
1443
184k
                                                   (uint32_t)packet_remaining);
1444
184k
            if (cleartext_packet == NULL) {
1445
0
                goto error;
1446
0
            }
1447
1448
184k
            if (packet_second_block != NULL) {
1449
184k
                if (crypto != NULL) {
1450
132k
                    mac = packet_second_block + packet_remaining;
1451
1452
132k
                    if (crypto->in_hmac != SSH_HMAC_NONE && etm) {
1453
0
                        rc = ssh_packet_hmac_verify(session,
1454
0
                                                    data,
1455
0
                                                    processed,
1456
0
                                                    mac,
1457
0
                                                    crypto->in_hmac);
1458
0
                        if (rc < 0) {
1459
0
                            ssh_set_error(session, SSH_FATAL, "HMAC error");
1460
0
                            goto error;
1461
0
                        }
1462
0
                    }
1463
                    /*
1464
                     * Decrypt the packet. In case of EtM mode, the length is
1465
                     * already known as it's unencrypted. In the other case,
1466
                     * lenfield_blocksize bytes already have been decrypted.
1467
                     */
1468
132k
                    if (packet_remaining > 0) {
1469
113k
                        rc = ssh_packet_decrypt(session,
1470
113k
                                                cleartext_packet,
1471
113k
                                                (uint8_t *)data,
1472
113k
                                                packet_offset,
1473
113k
                                                processed - packet_offset);
1474
113k
                        if (rc < 0) {
1475
0
                            ssh_set_error(session,
1476
0
                                          SSH_FATAL,
1477
0
                                          "Decryption error");
1478
0
                            goto error;
1479
0
                        }
1480
113k
                    }
1481
1482
132k
                    if (crypto->in_hmac != SSH_HMAC_NONE && !etm) {
1483
88.3k
                        ssh_buffer in = session->in_buffer;
1484
88.3k
                        rc = ssh_packet_hmac_verify(session,
1485
88.3k
                                                    ssh_buffer_get(in),
1486
88.3k
                                                    ssh_buffer_get_len(in),
1487
88.3k
                                                    mac,
1488
88.3k
                                                    crypto->in_hmac);
1489
88.3k
                        if (rc < 0) {
1490
0
                            ssh_set_error(session, SSH_FATAL, "HMAC error");
1491
0
                            goto error;
1492
0
                        }
1493
88.3k
                    }
1494
132k
                    processed += current_macsize;
1495
132k
                } else {
1496
51.8k
                    memcpy(cleartext_packet,
1497
51.8k
                           packet_second_block,
1498
51.8k
                           packet_remaining);
1499
51.8k
                }
1500
184k
            }
1501
1502
184k
#ifdef WITH_PCAP
1503
184k
            if (session->pcap_ctx != NULL) {
1504
0
                ssh_pcap_context_write(session->pcap_ctx,
1505
0
                                       SSH_PCAP_DIR_IN,
1506
0
                                       ssh_buffer_get(session->in_buffer),
1507
0
                                       ssh_buffer_get_len(session->in_buffer),
1508
0
                                       ssh_buffer_get_len(session->in_buffer));
1509
0
            }
1510
184k
#endif
1511
1512
184k
            if (!etm) {
1513
                /* skip the size field which has been processed before */
1514
184k
                ssh_buffer_pass_bytes(session->in_buffer, sizeof(uint32_t));
1515
184k
            }
1516
1517
184k
            rc = ssh_buffer_get_u8(session->in_buffer, &padding);
1518
184k
            if (rc == 0) {
1519
0
                ssh_set_error(session,
1520
0
                              SSH_FATAL,
1521
0
                              "Packet too short to read padding");
1522
0
                goto error;
1523
0
            }
1524
1525
184k
            if (padding > ssh_buffer_get_len(session->in_buffer)) {
1526
0
                ssh_set_error(session,
1527
0
                              SSH_FATAL,
1528
0
                              "Invalid padding: %d (%" PRIu32 " left)",
1529
0
                              padding,
1530
0
                              ssh_buffer_get_len(session->in_buffer));
1531
0
                goto error;
1532
0
            }
1533
184k
            ssh_buffer_pass_bytes_end(session->in_buffer, padding);
1534
184k
            compsize = ssh_buffer_get_len(session->in_buffer);
1535
1536
184k
            if (crypto && crypto->do_compress_in &&
1537
0
                ssh_buffer_get_len(session->in_buffer) > 0) {
1538
0
                rc = decompress_buffer(session, session->in_buffer,
1539
0
                                       MAX_PACKET_LEN);
1540
0
                if (rc < 0) {
1541
0
                    goto error;
1542
0
                }
1543
0
            }
1544
184k
            payloadsize = ssh_buffer_get_len(session->in_buffer);
1545
184k
            if (session->recv_seq == UINT32_MAX) {
1546
                /* Overflowing sequence numbers is always fishy */
1547
0
                if (crypto == NULL) {
1548
                    /* don't allow sequence number overflow when unencrypted */
1549
0
                    ssh_set_error(session,
1550
0
                                  SSH_FATAL,
1551
0
                                  "Incoming sequence number overflow");
1552
0
                    goto error;
1553
0
                } else {
1554
0
                    SSH_LOG(SSH_LOG_WARNING,
1555
0
                            "Incoming sequence number overflow");
1556
0
                }
1557
0
            }
1558
184k
            session->recv_seq++;
1559
184k
            if (crypto != NULL) {
1560
132k
                struct ssh_cipher_struct *cipher = NULL;
1561
1562
132k
                cipher = crypto->in_cipher;
1563
132k
                cipher->packets++;
1564
132k
                cipher->blocks += payloadsize / cipher->blocksize;
1565
132k
            }
1566
184k
            if (session->raw_counter != NULL) {
1567
0
                session->raw_counter->in_bytes += payloadsize;
1568
0
                session->raw_counter->in_packets++;
1569
0
            }
1570
1571
            /*
1572
             * We don't want to rewrite a new packet while still executing the
1573
             * packet callbacks
1574
             */
1575
184k
            session->packet_state = PACKET_STATE_PROCESSING;
1576
184k
            ssh_packet_parse_type(session);
1577
184k
            SSH_LOG(SSH_LOG_PACKET,
1578
184k
                    "packet: read type %hhd [len=%" PRIu32 ",padding=%hhd,"
1579
184k
                    "comp=%" PRIu32 ",payload=%" PRIu32 "]",
1580
184k
                    session->in_packet.type, packet_len, padding, compsize,
1581
184k
                    payloadsize);
1582
184k
            if (crypto == NULL) {
1583
                /* In strict kex, only a few packets are allowed. Taint the session
1584
                 * if we received packets that are normally allowed but to be
1585
                 * refused if we are in strict kex when KEX is over.
1586
                 */
1587
51.8k
                uint8_t type = session->in_packet.type;
1588
1589
51.8k
                if (type != SSH2_MSG_KEXINIT && type != SSH2_MSG_NEWKEYS &&
1590
17.2k
                    (type < SSH2_MSG_KEXDH_INIT ||
1591
17.2k
                     type > SSH2_MSG_KEX_DH_GEX_REQUEST)) {
1592
0
                    session->flags |= SSH_SESSION_FLAG_KEX_TAINTED;
1593
0
                }
1594
51.8k
            }
1595
            /* Check if the packet is expected */
1596
184k
            filter_result = ssh_packet_incoming_filter(session);
1597
1598
184k
            switch (filter_result) {
1599
184k
            case SSH_PACKET_ALLOWED:
1600
                /* Execute callbacks */
1601
184k
                ssh_packet_process(session, session->in_packet.type);
1602
184k
                break;
1603
0
            case SSH_PACKET_DENIED:
1604
0
                ssh_set_error(session,
1605
0
                              SSH_FATAL,
1606
0
                              "Packet filter: rejected packet (type %d)",
1607
0
                              session->in_packet.type);
1608
0
                goto error;
1609
0
            case SSH_PACKET_UNKNOWN:
1610
0
                if (crypto == NULL) {
1611
0
                    session->flags |= SSH_SESSION_FLAG_KEX_TAINTED;
1612
0
                }
1613
0
                ssh_packet_send_unimplemented(session, session->recv_seq - 1);
1614
0
                break;
1615
184k
            }
1616
1617
184k
            session->packet_state = PACKET_STATE_INIT;
1618
184k
            if (processed < receivedlen) {
1619
54.9k
                SSH_LOG(SSH_LOG_PACKET,
1620
54.9k
                        "packet: %zu bytes still remaining in socket buffer "
1621
54.9k
                        "after processing",
1622
54.9k
                        receivedlen-processed);
1623
54.9k
            }
1624
1625
184k
            ok = ssh_packet_need_rekey(session, 0);
1626
184k
            if (ok) {
1627
0
                SSH_LOG(SSH_LOG_PACKET, "Incoming packet triggered rekey");
1628
0
                rc = ssh_send_rekex(session);
1629
0
                if (rc != SSH_OK) {
1630
0
                    SSH_LOG(SSH_LOG_PACKET, "Rekey failed: rc = %d", rc);
1631
0
                    goto error;
1632
0
                }
1633
0
            }
1634
1635
184k
            return processed;
1636
0
        case PACKET_STATE_PROCESSING:
1637
0
            SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
1638
0
            return 0;
1639
649k
    }
1640
1641
0
    ssh_set_error(session,
1642
0
                  SSH_FATAL,
1643
0
                  "Invalid state into packet_read2(): %d",
1644
0
                  session->packet_state);
1645
1646
0
error:
1647
0
    session->session_state = SSH_SESSION_STATE_ERROR;
1648
0
    SSH_LOG(SSH_LOG_PACKET, "Packet: processed %zu bytes", processed);
1649
0
    return processed;
1650
0
}
1651
1652
static void ssh_packet_socket_controlflow_callback(int code, void *userdata)
1653
101k
{
1654
101k
    ssh_session session = userdata;
1655
101k
    struct ssh_iterator *it = NULL;
1656
101k
    ssh_channel channel = NULL;
1657
1658
101k
    if (code == SSH_SOCKET_FLOW_WRITEWONTBLOCK) {
1659
101k
        SSH_LOG(SSH_LOG_TRACE, "sending channel_write_wontblock callback");
1660
1661
        /* the out pipe is empty so we can forward this to channels */
1662
101k
        it = ssh_list_get_iterator(session->channels);
1663
127k
        while (it != NULL) {
1664
25.9k
            channel = ssh_iterator_value(ssh_channel, it);
1665
25.9k
            ssh_callbacks_execute_list(channel->callbacks,
1666
25.9k
                                       ssh_channel_callbacks,
1667
25.9k
                                       channel_write_wontblock_function,
1668
25.9k
                                       session,
1669
25.9k
                                       channel,
1670
25.9k
                                       channel->remote_window);
1671
25.9k
            it = it->next;
1672
25.9k
        }
1673
101k
    }
1674
101k
}
1675
1676
void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s)
1677
17.2k
{
1678
17.2k
    struct ssh_socket_callbacks_struct *callbacks = &session->socket_callbacks;
1679
1680
17.2k
    callbacks->data = ssh_packet_socket_callback;
1681
17.2k
    callbacks->connected = NULL;
1682
17.2k
    callbacks->controlflow = ssh_packet_socket_controlflow_callback;
1683
17.2k
    callbacks->userdata = session;
1684
17.2k
    ssh_socket_set_callbacks(s, callbacks);
1685
17.2k
}
1686
1687
/** @internal
1688
 * @brief sets the callbacks for the packet layer
1689
 */
1690
void
1691
ssh_packet_set_callbacks(ssh_session session, ssh_packet_callbacks callbacks)
1692
34.5k
{
1693
34.5k
    if (session->packet_callbacks == NULL) {
1694
17.2k
        session->packet_callbacks = ssh_list_new();
1695
17.2k
        if (session->packet_callbacks == NULL) {
1696
0
            ssh_set_error_oom(session);
1697
0
            return;
1698
0
        }
1699
17.2k
    }
1700
34.5k
    ssh_list_append(session->packet_callbacks, callbacks);
1701
34.5k
}
1702
1703
/** @internal
1704
 * @brief remove the callbacks from the packet layer
1705
 */
1706
void
1707
ssh_packet_remove_callbacks(ssh_session session, ssh_packet_callbacks callbacks)
1708
17.2k
{
1709
17.2k
    struct ssh_iterator *it = NULL;
1710
1711
17.2k
    it = ssh_list_find(session->packet_callbacks, callbacks);
1712
17.2k
    if (it != NULL) {
1713
17.2k
        ssh_list_remove(session->packet_callbacks, it);
1714
17.2k
    }
1715
17.2k
}
1716
1717
/** @internal
1718
 * @brief sets the default packet handlers
1719
 */
1720
void ssh_packet_set_default_callbacks(ssh_session session)
1721
17.2k
{
1722
17.2k
    struct ssh_packet_callbacks_struct *c = &session->default_packet_callbacks;
1723
1724
17.2k
    c->start = 1;
1725
17.2k
    c->n_callbacks = sizeof(default_packet_handlers) / sizeof(ssh_packet_callback);
1726
17.2k
    c->user = session;
1727
17.2k
    c->callbacks = default_packet_handlers;
1728
17.2k
    ssh_packet_set_callbacks(session, c);
1729
17.2k
}
1730
1731
/** @internal
1732
 * @brief dispatch the call of packet handlers callbacks for a received packet
1733
 * @param type type of packet
1734
 */
1735
void ssh_packet_process(ssh_session session, uint8_t type)
1736
184k
{
1737
184k
    struct ssh_iterator *i = NULL;
1738
184k
    int rc = SSH_PACKET_NOT_USED;
1739
184k
    ssh_packet_callbacks cb;
1740
1741
184k
    SSH_LOG(SSH_LOG_PACKET, "Dispatching handler for packet type %d", type);
1742
184k
    if (session->packet_callbacks == NULL) {
1743
0
        SSH_LOG(SSH_LOG_RARE, "Packet callback is not initialized !");
1744
0
        return;
1745
0
    }
1746
1747
184k
    i = ssh_list_get_iterator(session->packet_callbacks);
1748
201k
    while (i != NULL) {
1749
201k
        cb = ssh_iterator_value(ssh_packet_callbacks, i);
1750
201k
        i = i->next;
1751
1752
201k
        if (!cb) {
1753
0
            continue;
1754
0
        }
1755
1756
201k
        if (cb->start > type) {
1757
0
            continue;
1758
0
        }
1759
1760
201k
        if (cb->start + cb->n_callbacks <= type) {
1761
0
            continue;
1762
0
        }
1763
1764
201k
        if (cb->callbacks[type - cb->start] == NULL) {
1765
8.64k
            continue;
1766
8.64k
        }
1767
1768
192k
        rc = cb->callbacks[type - cb->start](session, type, session->in_buffer,
1769
192k
                                             cb->user);
1770
192k
        if (rc == SSH_PACKET_USED) {
1771
184k
            break;
1772
184k
        }
1773
192k
    }
1774
1775
184k
    if (rc == SSH_PACKET_NOT_USED) {
1776
0
        SSH_LOG(SSH_LOG_RARE, "Couldn't do anything with packet type %d", type);
1777
0
        rc = ssh_packet_send_unimplemented(session, session->recv_seq - 1);
1778
0
        if (rc != SSH_OK) {
1779
0
            SSH_LOG(SSH_LOG_RARE, "Failed to send unimplemented: %s",
1780
0
                    ssh_get_error(session));
1781
0
        }
1782
0
        if (session->current_crypto == NULL) {
1783
0
            session->flags |= SSH_SESSION_FLAG_KEX_TAINTED;
1784
0
        }
1785
0
    }
1786
184k
}
1787
1788
/** @internal
1789
 * @brief sends a SSH_MSG_NEWKEYS when enabling the new negotiated ciphers
1790
 * @param session the SSH session
1791
 * @return SSH_ERROR on error, else SSH_OK
1792
 */
1793
int ssh_packet_send_newkeys(ssh_session session)
1794
17.2k
{
1795
17.2k
    int rc;
1796
1797
    /* Send the MSG_NEWKEYS */
1798
17.2k
    rc = ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
1799
17.2k
    if (rc < 0) {
1800
0
        return rc;
1801
0
    }
1802
1803
17.2k
    rc = ssh_packet_send(session);
1804
17.2k
    if (rc == SSH_ERROR) {
1805
0
        return rc;
1806
0
    }
1807
17.2k
    SSH_LOG(SSH_LOG_DEBUG, "SSH_MSG_NEWKEYS sent");
1808
17.2k
    return rc;
1809
17.2k
}
1810
1811
/** @internal
1812
 * @brief sends a SSH_MSG_UNIMPLEMENTED answer to an unhandled packet
1813
 * @param session the SSH session
1814
 * @param seqnum the sequence number of the unknown packet
1815
 * @return SSH_ERROR on error, else SSH_OK
1816
 */
1817
0
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){
1818
0
    int rc;
1819
1820
0
    rc = ssh_buffer_pack(session->out_buffer,
1821
0
                         "bd",
1822
0
                         SSH2_MSG_UNIMPLEMENTED,
1823
0
                         seqnum);
1824
0
    if (rc != SSH_OK) {
1825
0
        ssh_set_error_oom(session);
1826
0
        return SSH_ERROR;
1827
0
    }
1828
0
    rc = ssh_packet_send(session);
1829
1830
0
    return rc;
1831
0
}
1832
1833
/** @internal
1834
 * @brief handles a SSH_MSG_UNIMPLEMENTED packet
1835
 */
1836
0
SSH_PACKET_CALLBACK(ssh_packet_unimplemented){
1837
0
    uint32_t seq;
1838
0
    int rc;
1839
1840
0
    (void)session; /* unused */
1841
0
    (void)type;
1842
0
    (void)user;
1843
1844
0
    rc = ssh_buffer_unpack(packet, "d", &seq);
1845
0
    if (rc != SSH_OK) {
1846
0
        SSH_LOG(SSH_LOG_TRACE,
1847
0
                "Could not unpack SSH_MSG_UNIMPLEMENTED packet");
1848
0
    }
1849
1850
0
    SSH_LOG(SSH_LOG_RARE,
1851
0
            "Received SSH_MSG_UNIMPLEMENTED (sequence number %" PRIu32 ")",seq);
1852
1853
0
    return SSH_PACKET_USED;
1854
0
}
1855
1856
/** @internal
1857
 * @parse the "Type" header field of a packet and updates the session
1858
 */
1859
int ssh_packet_parse_type(struct ssh_session_struct *session)
1860
184k
{
1861
184k
    session->in_packet = (struct packet_struct) {
1862
184k
        .type = 0,
1863
184k
    };
1864
1865
184k
    if (session->in_buffer == NULL) {
1866
0
        return SSH_ERROR;
1867
0
    }
1868
1869
184k
    if (ssh_buffer_get_u8(session->in_buffer, &session->in_packet.type) == 0) {
1870
0
        ssh_set_error(session, SSH_FATAL, "Packet too short to read type");
1871
0
        return SSH_ERROR;
1872
0
    }
1873
1874
184k
    session->in_packet.valid = 1;
1875
1876
184k
    return SSH_OK;
1877
184k
}
1878
1879
/*
1880
 * This function places the outgoing packet buffer into an outgoing
1881
 * socket buffer
1882
 */
1883
210k
static int ssh_packet_write(ssh_session session) {
1884
210k
  int rc = SSH_ERROR;
1885
1886
210k
  rc=ssh_socket_write(session->socket,
1887
210k
      ssh_buffer_get(session->out_buffer),
1888
210k
      ssh_buffer_get_len(session->out_buffer));
1889
1890
210k
  return rc;
1891
210k
}
1892
1893
static int packet_send2(ssh_session session)
1894
210k
{
1895
210k
    unsigned int blocksize = 8;
1896
210k
    unsigned int lenfield_blocksize = 0;
1897
210k
    enum ssh_hmac_e hmac_type;
1898
210k
    uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
1899
210k
    struct ssh_crypto_struct *crypto = NULL;
1900
210k
    unsigned char *hmac = NULL;
1901
210k
    uint8_t padding_data[32] = { 0 };
1902
210k
    uint8_t padding_size;
1903
210k
    uint32_t finallen, payloadsize, compsize;
1904
210k
    uint8_t header[5] = {0};
1905
210k
    uint8_t type, *payload;
1906
210k
    int rc = SSH_ERROR;
1907
210k
    bool etm = false;
1908
210k
    int etm_packet_offset = 0;
1909
1910
210k
    crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_OUT);
1911
210k
    if (crypto) {
1912
158k
        blocksize = crypto->out_cipher->blocksize;
1913
158k
        lenfield_blocksize = crypto->out_cipher->lenfield_blocksize;
1914
158k
        hmac_type = crypto->out_hmac;
1915
158k
        etm = crypto->out_hmac_etm;
1916
158k
    } else {
1917
51.8k
        hmac_type = session->next_crypto->out_hmac;
1918
51.8k
    }
1919
1920
210k
    payload = (uint8_t *)ssh_buffer_get(session->out_buffer);
1921
210k
    type = payload[0]; /* type is the first byte of the packet now */
1922
1923
210k
    payloadsize = currentlen;
1924
210k
    if (etm) {
1925
0
        etm_packet_offset = sizeof(uint32_t);
1926
0
        lenfield_blocksize = 0;
1927
0
    }
1928
1929
210k
    if (crypto != NULL && crypto->do_compress_out &&
1930
0
        ssh_buffer_get_len(session->out_buffer) > 0) {
1931
0
        rc = compress_buffer(session,session->out_buffer);
1932
0
        if (rc < 0) {
1933
0
            goto error;
1934
0
        }
1935
0
        currentlen = ssh_buffer_get_len(session->out_buffer);
1936
0
    }
1937
210k
    compsize = currentlen;
1938
    /* compressed payload + packet len (4) + padding_size len (1) */
1939
    /* totallen - lenfield_blocksize - etm_packet_offset must be equal to 0 (mod blocksize) */
1940
210k
    padding_size = (blocksize - ((blocksize - lenfield_blocksize - etm_packet_offset + currentlen + 5) % blocksize));
1941
210k
    if (padding_size < 4) {
1942
90.6k
        padding_size += blocksize;
1943
90.6k
    }
1944
1945
210k
    if (crypto != NULL) {
1946
158k
        int ok;
1947
1948
158k
        ok = ssh_get_random(padding_data, padding_size, 0);
1949
158k
        if (!ok) {
1950
0
            ssh_set_error(session, SSH_FATAL, "PRNG error");
1951
0
            goto error;
1952
0
        }
1953
158k
    }
1954
1955
210k
    finallen = currentlen - etm_packet_offset + padding_size + 1;
1956
1957
210k
    PUSH_BE_U32(header, 0, finallen);
1958
210k
    PUSH_BE_U8(header, 4, padding_size);
1959
1960
210k
    rc = ssh_buffer_prepend_data(session->out_buffer,
1961
210k
                                 header,
1962
210k
                                 sizeof(header));
1963
210k
    if (rc < 0) {
1964
0
        goto error;
1965
0
    }
1966
1967
210k
    rc = ssh_buffer_add_data(session->out_buffer, padding_data, padding_size);
1968
210k
    if (rc < 0) {
1969
0
        goto error;
1970
0
    }
1971
1972
210k
#ifdef WITH_PCAP
1973
210k
    if (session->pcap_ctx != NULL) {
1974
0
        ssh_pcap_context_write(session->pcap_ctx,
1975
0
                               SSH_PCAP_DIR_OUT,
1976
0
                               ssh_buffer_get(session->out_buffer),
1977
0
                               ssh_buffer_get_len(session->out_buffer),
1978
0
                               ssh_buffer_get_len(session->out_buffer));
1979
0
    }
1980
210k
#endif
1981
1982
210k
    hmac = ssh_packet_encrypt(session,
1983
210k
                              ssh_buffer_get(session->out_buffer),
1984
210k
                              ssh_buffer_get_len(session->out_buffer));
1985
    /* XXX This returns null before switching on crypto, with none MAC
1986
     * and on various errors.
1987
     * We should distinguish between these cases to avoid hiding errors. */
1988
210k
    if (hmac != NULL) {
1989
158k
        rc = ssh_buffer_add_data(session->out_buffer,
1990
158k
                                 hmac,
1991
158k
                                 (uint32_t)hmac_digest_len(hmac_type));
1992
158k
        if (rc < 0) {
1993
0
            goto error;
1994
0
        }
1995
158k
    }
1996
1997
210k
    rc = ssh_packet_write(session);
1998
210k
    if (rc == SSH_ERROR) {
1999
0
        goto error;
2000
0
    }
2001
210k
    session->send_seq++;
2002
210k
    if (crypto != NULL) {
2003
158k
        struct ssh_cipher_struct *cipher = NULL;
2004
2005
158k
        cipher = crypto->out_cipher;
2006
158k
        cipher->packets++;
2007
158k
        cipher->blocks += payloadsize / cipher->blocksize;
2008
158k
    }
2009
210k
    if (session->raw_counter != NULL) {
2010
0
        session->raw_counter->out_bytes += payloadsize;
2011
0
        session->raw_counter->out_packets++;
2012
0
    }
2013
2014
210k
    SSH_LOG(SSH_LOG_PACKET,
2015
210k
            "packet: wrote [type=%u, len=%" PRIu32 ", padding_size=%hhd, comp=%" PRIu32 ", "
2016
210k
            "payload=%" PRIu32 "]",
2017
210k
            type,
2018
210k
            finallen,
2019
210k
            padding_size,
2020
210k
            compsize,
2021
210k
            payloadsize);
2022
2023
210k
    rc = ssh_buffer_reinit(session->out_buffer);
2024
210k
    if (rc < 0) {
2025
0
        rc = SSH_ERROR;
2026
0
        goto error;
2027
0
    }
2028
2029
    /* We sent the NEWKEYS so any further packet needs to be encrypted
2030
     * with the new keys. We can not switch both directions (need to decrypt
2031
     * peer NEWKEYS) and we do not want to wait for the peer NEWKEYS
2032
     * too, so we will switch only the OUT direction now.
2033
     */
2034
210k
    if (type == SSH2_MSG_NEWKEYS) {
2035
17.2k
        rc = ssh_packet_set_newkeys(session, SSH_DIRECTION_OUT);
2036
17.2k
    }
2037
210k
error:
2038
210k
    return rc; /* SSH_OK, AGAIN or ERROR */
2039
210k
}
2040
2041
static bool
2042
ssh_packet_is_kex(unsigned char type)
2043
0
{
2044
0
    return type >= SSH2_MSG_DISCONNECT &&
2045
0
           type <= SSH2_MSG_KEX_DH_GEX_REQUEST &&
2046
0
           type != SSH2_MSG_SERVICE_REQUEST &&
2047
0
           type != SSH2_MSG_SERVICE_ACCEPT &&
2048
0
           type != SSH2_MSG_IGNORE &&
2049
0
           type != SSH2_MSG_EXT_INFO;
2050
0
}
2051
2052
static bool
2053
ssh_packet_in_rekey(ssh_session session)
2054
210k
{
2055
    /* We know we are rekeying if we are authenticated and the DH
2056
     * status is not finished, but we only queue packets until we've
2057
     * sent our NEWKEYS.
2058
     */
2059
210k
    return (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) &&
2060
115k
           (session->dh_handshake_state != DH_STATE_FINISHED) &&
2061
0
           (session->dh_handshake_state != DH_STATE_NEWKEYS_SENT);
2062
210k
}
2063
2064
int ssh_packet_send(ssh_session session)
2065
218k
{
2066
218k
    uint32_t payloadsize;
2067
218k
    uint8_t type, *payload;
2068
218k
    bool need_rekey, in_rekey;
2069
218k
    int rc;
2070
2071
218k
    if (session->socket == NULL || !ssh_socket_is_open(session->socket)) {
2072
8.64k
        ssh_buffer_reinit(session->out_buffer);
2073
8.64k
        return SSH_ERROR;
2074
8.64k
    }
2075
2076
210k
    payloadsize = ssh_buffer_get_len(session->out_buffer);
2077
210k
    if (payloadsize < 1) {
2078
0
        return SSH_ERROR;
2079
0
    }
2080
2081
210k
    payload = (uint8_t *)ssh_buffer_get(session->out_buffer);
2082
210k
    type = payload[0]; /* type is the first byte of the packet now */
2083
210k
    need_rekey = ssh_packet_need_rekey(session, payloadsize);
2084
210k
    in_rekey = ssh_packet_in_rekey(session);
2085
2086
    /* The rekey is triggered here. After that, only the key exchange
2087
     * packets can be sent, until we send our NEWKEYS.
2088
     */
2089
210k
    if (need_rekey || (in_rekey && !ssh_packet_is_kex(type))) {
2090
0
        if (need_rekey) {
2091
0
            SSH_LOG(SSH_LOG_PACKET, "Outgoing packet triggered rekey");
2092
0
        }
2093
        /* Queue the current packet -- we will send it after the rekey */
2094
0
        SSH_LOG(SSH_LOG_PACKET, "Queuing packet type %d", type);
2095
0
        rc = ssh_list_append(session->out_queue, session->out_buffer);
2096
0
        if (rc != SSH_OK) {
2097
0
            return SSH_ERROR;
2098
0
        }
2099
0
        session->out_buffer = ssh_buffer_new();
2100
0
        if (session->out_buffer == NULL) {
2101
0
            ssh_set_error_oom(session);
2102
0
            return SSH_ERROR;
2103
0
        }
2104
2105
0
        if (need_rekey) {
2106
            /* Send the KEXINIT packet instead.
2107
             * This recursively calls the packet_send(), but it should
2108
             * not get into rekeying again.
2109
             * After that we need to handle the key exchange responses
2110
             * up to the point where we can send the rest of the queue.
2111
             */
2112
0
            return ssh_send_rekex(session);
2113
0
        }
2114
0
        return SSH_OK;
2115
0
    }
2116
2117
    /* Send the packet normally */
2118
210k
    rc = packet_send2(session);
2119
2120
    /* We finished the key exchange so we can try to send our queue now */
2121
210k
    if (rc == SSH_OK && type == SSH2_MSG_NEWKEYS) {
2122
17.2k
        struct ssh_iterator *it = NULL;
2123
2124
17.2k
        if (session->flags & SSH_SESSION_FLAG_KEX_STRICT) {
2125
            /* reset packet sequence number when running in strict kex mode */
2126
17.2k
            session->send_seq = 0;
2127
17.2k
        }
2128
17.2k
        for (it = ssh_list_get_iterator(session->out_queue);
2129
17.2k
             it != NULL;
2130
17.2k
             it = ssh_list_get_iterator(session->out_queue)) {
2131
0
            struct ssh_buffer_struct *next_buffer = NULL;
2132
2133
            /* Peek only -- do not remove from queue yet */
2134
0
            next_buffer = (struct ssh_buffer_struct *)it->data;
2135
0
            payloadsize = ssh_buffer_get_len(next_buffer);
2136
0
            if (ssh_packet_need_rekey(session, payloadsize)) {
2137
                /* Sigh ... we still can not send this packet. Repeat. */
2138
0
                SSH_LOG(SSH_LOG_PACKET, "Queued packet triggered rekey");
2139
0
                return ssh_send_rekex(session);
2140
0
            }
2141
0
            SSH_BUFFER_FREE(session->out_buffer);
2142
0
            session->out_buffer = ssh_list_pop_head(struct ssh_buffer_struct *,
2143
0
                                                    session->out_queue);
2144
0
            payload = (uint8_t *)ssh_buffer_get(session->out_buffer);
2145
0
            type = payload[0];
2146
0
            SSH_LOG(SSH_LOG_PACKET, "Dequeue packet type %d", type);
2147
0
            rc = packet_send2(session);
2148
0
            if (rc != SSH_OK) {
2149
0
                return rc;
2150
0
            }
2151
0
        }
2152
17.2k
    }
2153
2154
210k
    return rc;
2155
210k
}
2156
2157
/**
2158
 * @brief Check whether the ping@openssh.com extension is available.
2159
 *
2160
 * This function allows an application to determine whether ping can be sent
2161
 * to the current peer.
2162
 *
2163
 * @note Use ssh_send_ping() only after verifying support with this function.
2164
 *
2165
 * @param[in]  session  The SSH session handle.
2166
 *
2167
 * @return true if the extension was negotiated, false otherwise or if
2168
 *         session is NULL.
2169
 *
2170
 * @see ssh_send_ping()
2171
 */
2172
bool ssh_is_ping_supported(ssh_session session)
2173
0
{
2174
0
    if (session == NULL) {
2175
0
        return false;
2176
0
    }
2177
0
    return (session->extensions & SSH_EXT_PING) != 0;
2178
0
}
2179
2180
/**
2181
 * @brief Send a transport-level SSH ping message.
2182
 *
2183
 * This function sends a SSH2_MSG_PING packet to the remote peer.
2184
 * Optional payload data is sent as part of the ping message.
2185
 * Use ssh_is_ping_supported() to check whether the remote peer supports
2186
 * pings before calling this function.
2187
 *
2188
 * @param[in]  session  The SSH session handle.
2189
 * @param[in]  data     Optional payload data (may be NULL).
2190
 * @param[in]  len      Length of the payload data in bytes.
2191
 *
2192
 * @return SSH_OK on success, SSH_ERROR on failure.
2193
 *
2194
 * @see ssh_is_ping_supported()
2195
 */
2196
int ssh_send_ping(ssh_session session, const void *data, size_t len)
2197
0
{
2198
0
    int rc;
2199
0
    ssh_string payload = NULL;
2200
2201
0
    if (session == NULL) {
2202
0
        return SSH_ERROR;
2203
0
    }
2204
2205
    /* Only send ping if the peer has advertised ping@openssh.com */
2206
0
    if (!ssh_is_ping_supported(session)) {
2207
0
        ssh_set_error(session,
2208
0
                      SSH_REQUEST_DENIED,
2209
0
                      "ping@openssh.com extension was not negotiated");
2210
0
        return SSH_ERROR;
2211
0
    }
2212
2213
0
    payload = ssh_string_from_data(data, len);
2214
0
    if (payload == NULL) {
2215
0
        ssh_set_error_oom(session);
2216
0
        return SSH_ERROR;
2217
0
    }
2218
2219
0
    rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_PING, payload);
2220
0
    SSH_STRING_FREE(payload);
2221
0
    if (rc != SSH_OK) {
2222
0
        ssh_set_error_oom(session);
2223
0
        ssh_buffer_reinit(session->out_buffer);
2224
0
        return SSH_ERROR;
2225
0
    }
2226
2227
0
    rc = ssh_packet_send(session);
2228
0
    if (rc != SSH_OK) {
2229
0
        return SSH_ERROR;
2230
0
    }
2231
0
    session->pending_pings++;
2232
2233
0
    return SSH_OK;
2234
0
}
2235
2236
static void
2237
ssh_init_rekey_state(struct ssh_session_struct *session,
2238
                     struct ssh_cipher_struct *cipher)
2239
34.5k
{
2240
    /* Reset the counters: should be NOOP */
2241
34.5k
    cipher->packets = 0;
2242
34.5k
    cipher->blocks = 0;
2243
2244
    /* Default rekey limits for ciphers as specified in RFC4344, Section 3.2 */
2245
34.5k
    if (cipher->blocksize >= 16) {
2246
        /* For larger block size (L bits) use maximum of 2**(L/4) blocks */
2247
25.9k
        cipher->max_blocks = (uint64_t)1 << (cipher->blocksize*2);
2248
25.9k
    } else {
2249
        /* For smaller blocks use limit of 1 GB as recommended in RFC4253 */
2250
8.64k
        cipher->max_blocks = ((uint64_t)1 << 30) / cipher->blocksize;
2251
8.64k
    }
2252
    /* If we have limit provided by user, use the smaller one */
2253
34.5k
    if (session->opts.rekey_data != 0) {
2254
0
        cipher->max_blocks = MIN(cipher->max_blocks,
2255
0
                                 session->opts.rekey_data / cipher->blocksize);
2256
0
    }
2257
2258
34.5k
    SSH_LOG(SSH_LOG_DEBUG,
2259
34.5k
            "Set rekey after %" PRIu64 " blocks",
2260
34.5k
            cipher->max_blocks);
2261
34.5k
}
2262
2263
/*
2264
 * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and
2265
 * current_crypto for our desired direction
2266
 */
2267
int
2268
ssh_packet_set_newkeys(ssh_session session,
2269
                       enum ssh_crypto_direction_e direction)
2270
34.5k
{
2271
34.5k
    struct ssh_cipher_struct *in_cipher = NULL, *out_cipher = NULL;
2272
34.5k
    int rc;
2273
2274
34.5k
    SSH_LOG(SSH_LOG_TRACE,
2275
34.5k
            "called, direction =%s%s",
2276
34.5k
            direction & SSH_DIRECTION_IN ? " IN " : "",
2277
34.5k
            direction & SSH_DIRECTION_OUT ? " OUT " : "");
2278
2279
34.5k
    if (session->next_crypto == NULL) {
2280
0
        return SSH_ERROR;
2281
0
    }
2282
2283
34.5k
    session->next_crypto->used |= direction;
2284
34.5k
    if (session->current_crypto != NULL) {
2285
0
        if (session->current_crypto->used & direction) {
2286
0
            SSH_LOG(SSH_LOG_TRACE, "This direction isn't used anymore.");
2287
0
        }
2288
        /* Mark the current requested direction unused */
2289
0
        session->current_crypto->used &= ~direction;
2290
0
    }
2291
2292
    /* Both sides switched: do the actual switch now */
2293
34.5k
    if (session->next_crypto->used == SSH_DIRECTION_BOTH) {
2294
17.2k
        size_t session_id_len;
2295
2296
17.2k
        if (session->current_crypto != NULL) {
2297
0
            crypto_free(session->current_crypto);
2298
0
            session->current_crypto = NULL;
2299
0
        }
2300
2301
17.2k
        session->current_crypto = session->next_crypto;
2302
17.2k
        session->current_crypto->used = SSH_DIRECTION_BOTH;
2303
2304
        /* Initialize the next_crypto structure */
2305
17.2k
        session->next_crypto = crypto_new();
2306
17.2k
        if (session->next_crypto == NULL) {
2307
0
            ssh_set_error_oom(session);
2308
0
            return SSH_ERROR;
2309
0
        }
2310
2311
17.2k
        session_id_len = session->current_crypto->session_id_len;
2312
17.2k
        session->next_crypto->session_id = malloc(session_id_len);
2313
17.2k
        if (session->next_crypto->session_id == NULL) {
2314
0
            ssh_set_error_oom(session);
2315
0
            return SSH_ERROR;
2316
0
        }
2317
2318
17.2k
        memcpy(session->next_crypto->session_id,
2319
17.2k
               session->current_crypto->session_id,
2320
17.2k
               session_id_len);
2321
17.2k
        session->next_crypto->session_id_len = session_id_len;
2322
2323
17.2k
        return SSH_OK;
2324
17.2k
    }
2325
2326
    /* Initialize common structures so the next context can be used in
2327
     * either direction */
2328
17.2k
    if (session->client) {
2329
        /* The server has this part already done */
2330
8.64k
        rc = ssh_make_sessionid(session);
2331
8.64k
        if (rc != SSH_OK) {
2332
0
            return SSH_ERROR;
2333
0
        }
2334
2335
        /*
2336
         * Set the cryptographic functions for the next crypto
2337
         * (it is needed for ssh_generate_session_keys for key lengths)
2338
         */
2339
8.64k
        rc = crypt_set_algorithms_client(session);
2340
8.64k
        if (rc < 0) {
2341
0
            return SSH_ERROR;
2342
0
        }
2343
8.64k
    }
2344
2345
17.2k
    if (ssh_generate_session_keys(session) < 0) {
2346
0
        return SSH_ERROR;
2347
0
    }
2348
2349
17.2k
    in_cipher = session->next_crypto->in_cipher;
2350
17.2k
    out_cipher = session->next_crypto->out_cipher;
2351
17.2k
    if (in_cipher == NULL || out_cipher == NULL) {
2352
0
        return SSH_ERROR;
2353
0
    }
2354
2355
    /* Initialize rekeying states */
2356
17.2k
    ssh_init_rekey_state(session, out_cipher);
2357
17.2k
    ssh_init_rekey_state(session, in_cipher);
2358
17.2k
    if (session->opts.rekey_time != 0) {
2359
0
        ssh_timestamp_init(&session->last_rekey_time);
2360
0
        SSH_LOG(SSH_LOG_DEBUG, "Set rekey after %" PRIu32 " seconds",
2361
0
                session->opts.rekey_time/1000);
2362
0
    }
2363
2364
17.2k
    if (in_cipher->set_decrypt_key) {
2365
        /* Initialize the encryption and decryption keys in next_crypto */
2366
12.9k
        rc = in_cipher->set_decrypt_key(in_cipher,
2367
12.9k
                                        session->next_crypto->decryptkey,
2368
12.9k
                                        session->next_crypto->decryptIV);
2369
12.9k
        if (rc < 0) {
2370
            /* On error, make sure it is not used */
2371
0
            session->next_crypto->used = 0;
2372
0
            return SSH_ERROR;
2373
0
        }
2374
12.9k
    }
2375
2376
17.2k
    if (out_cipher->set_encrypt_key) {
2377
12.9k
        rc = out_cipher->set_encrypt_key(out_cipher,
2378
12.9k
                                         session->next_crypto->encryptkey,
2379
12.9k
                                         session->next_crypto->encryptIV);
2380
12.9k
        if (rc < 0) {
2381
            /* On error, make sure it is not used */
2382
0
            session->next_crypto->used = 0;
2383
0
            return SSH_ERROR;
2384
0
        }
2385
12.9k
    }
2386
2387
17.2k
    return SSH_OK;
2388
17.2k
}