tangled
alpha
login
or
join now
pyrox.dev
/
nixpkgs
0
fork
atom
lol
0
fork
atom
overview
issues
pulls
pipelines
libssh2: apply patch for CVE-2023-48795
Leona Maroni
2 years ago
1bfeb141
6b25f068
+465
2 changed files
expand all
collapse all
unified
split
pkgs
development
libraries
libssh2
CVE-2023-48795.patch
default.nix
+459
pkgs/development/libraries/libssh2/CVE-2023-48795.patch
reviewed
···
1
1
+
From d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a Mon Sep 17 00:00:00 2001
2
2
+
From: Michael Buckley <michael@buckleyisms.com>
3
3
+
Date: Thu, 30 Nov 2023 15:08:02 -0800
4
4
+
Subject: [PATCH] src: add 'strict KEX' to fix CVE-2023-48795 "Terrapin Attack"
5
5
+
6
6
+
Refs:
7
7
+
https://terrapin-attack.com/
8
8
+
https://seclists.org/oss-sec/2023/q4/292
9
9
+
https://osv.dev/list?ecosystem=&q=CVE-2023-48795
10
10
+
https://github.com/advisories/GHSA-45x7-px36-x8w8
11
11
+
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-48795
12
12
+
13
13
+
Fixes #1290
14
14
+
Closes #1291
15
15
+
---
16
16
+
src/kex.c | 63 +++++++++++++++++++++++------------
17
17
+
src/libssh2_priv.h | 18 +++++++---
18
18
+
src/packet.c | 83 +++++++++++++++++++++++++++++++++++++++++++---
19
19
+
src/packet.h | 2 +-
20
20
+
src/session.c | 3 ++
21
21
+
src/transport.c | 12 ++++++-
22
22
+
6 files changed, 149 insertions(+), 32 deletions(-)
23
23
+
24
24
+
diff --git a/src/kex.c b/src/kex.c
25
25
+
index 8e7b7f0af3..a7b301e157 100644
26
26
+
--- a/src/kex.c
27
27
+
+++ b/src/kex.c
28
28
+
@@ -3032,6 +3032,13 @@ kex_method_extension_negotiation = {
29
29
+
0,
30
30
+
};
31
31
+
32
32
+
+static const LIBSSH2_KEX_METHOD
33
33
+
+kex_method_strict_client_extension = {
34
34
+
+ "kex-strict-c-v00@openssh.com",
35
35
+
+ NULL,
36
36
+
+ 0,
37
37
+
+};
38
38
+
+
39
39
+
static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
40
40
+
#if LIBSSH2_ED25519
41
41
+
&kex_method_ssh_curve25519_sha256,
42
42
+
@@ -3050,6 +3057,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
43
43
+
&kex_method_diffie_helman_group1_sha1,
44
44
+
&kex_method_diffie_helman_group_exchange_sha1,
45
45
+
&kex_method_extension_negotiation,
46
46
+
+ &kex_method_strict_client_extension,
47
47
+
NULL
48
48
+
};
49
49
+
50
50
+
@@ -3302,13 +3310,13 @@ static int kexinit(LIBSSH2_SESSION * session)
51
51
+
return 0;
52
52
+
}
53
53
+
54
54
+
-/* kex_agree_instr
55
55
+
+/* _libssh2_kex_agree_instr
56
56
+
* Kex specific variant of strstr()
57
57
+
* Needle must be preceded by BOL or ',', and followed by ',' or EOL
58
58
+
*/
59
59
+
-static unsigned char *
60
60
+
-kex_agree_instr(unsigned char *haystack, size_t haystack_len,
61
61
+
- const unsigned char *needle, size_t needle_len)
62
62
+
+unsigned char *
63
63
+
+_libssh2_kex_agree_instr(unsigned char *haystack, size_t haystack_len,
64
64
+
+ const unsigned char *needle, size_t needle_len)
65
65
+
{
66
66
+
unsigned char *s;
67
67
+
unsigned char *end_haystack;
68
68
+
@@ -3393,7 +3401,7 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
69
69
+
while(s && *s) {
70
70
+
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
71
71
+
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
72
72
+
- if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
73
73
+
+ if(_libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
74
74
+
const LIBSSH2_HOSTKEY_METHOD *method =
75
75
+
(const LIBSSH2_HOSTKEY_METHOD *)
76
76
+
kex_get_method_by_name((char *) s, method_len,
77
77
+
@@ -3427,9 +3435,9 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
78
78
+
}
79
79
+
80
80
+
while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) {
81
81
+
- s = kex_agree_instr(hostkey, hostkey_len,
82
82
+
- (unsigned char *) (*hostkeyp)->name,
83
83
+
- strlen((*hostkeyp)->name));
84
84
+
+ s = _libssh2_kex_agree_instr(hostkey, hostkey_len,
85
85
+
+ (unsigned char *) (*hostkeyp)->name,
86
86
+
+ strlen((*hostkeyp)->name));
87
87
+
if(s) {
88
88
+
/* So far so good, but does it suit our purposes? (Encrypting vs
89
89
+
Signing) */
90
90
+
@@ -3463,6 +3471,12 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
91
91
+
{
92
92
+
const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
93
93
+
unsigned char *s;
94
94
+
+ const unsigned char *strict =
95
95
+
+ (unsigned char *)"kex-strict-s-v00@openssh.com";
96
96
+
+
97
97
+
+ if(_libssh2_kex_agree_instr(kex, kex_len, strict, 28)) {
98
98
+
+ session->kex_strict = 1;
99
99
+
+ }
100
100
+
101
101
+
if(session->kex_prefs) {
102
102
+
s = (unsigned char *) session->kex_prefs;
103
103
+
@@ -3470,7 +3484,7 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
104
104
+
while(s && *s) {
105
105
+
unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
106
106
+
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
107
107
+
- q = kex_agree_instr(kex, kex_len, s, method_len);
108
108
+
+ q = _libssh2_kex_agree_instr(kex, kex_len, s, method_len);
109
109
+
if(q) {
110
110
+
const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
111
111
+
kex_get_method_by_name((char *) s, method_len,
112
112
+
@@ -3504,9 +3518,9 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
113
113
+
}
114
114
+
115
115
+
while(*kexp && (*kexp)->name) {
116
116
+
- s = kex_agree_instr(kex, kex_len,
117
117
+
- (unsigned char *) (*kexp)->name,
118
118
+
- strlen((*kexp)->name));
119
119
+
+ s = _libssh2_kex_agree_instr(kex, kex_len,
120
120
+
+ (unsigned char *) (*kexp)->name,
121
121
+
+ strlen((*kexp)->name));
122
122
+
if(s) {
123
123
+
/* We've agreed on a key exchange method,
124
124
+
* Can we agree on a hostkey that works with this kex?
125
125
+
@@ -3550,7 +3564,7 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
126
126
+
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
127
127
+
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
128
128
+
129
129
+
- if(kex_agree_instr(crypt, crypt_len, s, method_len)) {
130
130
+
+ if(_libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) {
131
131
+
const LIBSSH2_CRYPT_METHOD *method =
132
132
+
(const LIBSSH2_CRYPT_METHOD *)
133
133
+
kex_get_method_by_name((char *) s, method_len,
134
134
+
@@ -3572,9 +3586,9 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
135
135
+
}
136
136
+
137
137
+
while(*cryptp && (*cryptp)->name) {
138
138
+
- s = kex_agree_instr(crypt, crypt_len,
139
139
+
- (unsigned char *) (*cryptp)->name,
140
140
+
- strlen((*cryptp)->name));
141
141
+
+ s = _libssh2_kex_agree_instr(crypt, crypt_len,
142
142
+
+ (unsigned char *) (*cryptp)->name,
143
143
+
+ strlen((*cryptp)->name));
144
144
+
if(s) {
145
145
+
endpoint->crypt = *cryptp;
146
146
+
return 0;
147
147
+
@@ -3614,7 +3628,7 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
148
148
+
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
149
149
+
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
150
150
+
151
151
+
- if(kex_agree_instr(mac, mac_len, s, method_len)) {
152
152
+
+ if(_libssh2_kex_agree_instr(mac, mac_len, s, method_len)) {
153
153
+
const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
154
154
+
kex_get_method_by_name((char *) s, method_len,
155
155
+
(const LIBSSH2_COMMON_METHOD **)
156
156
+
@@ -3635,8 +3649,9 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
157
157
+
}
158
158
+
159
159
+
while(*macp && (*macp)->name) {
160
160
+
- s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
161
161
+
- strlen((*macp)->name));
162
162
+
+ s = _libssh2_kex_agree_instr(mac, mac_len,
163
163
+
+ (unsigned char *) (*macp)->name,
164
164
+
+ strlen((*macp)->name));
165
165
+
if(s) {
166
166
+
endpoint->mac = *macp;
167
167
+
return 0;
168
168
+
@@ -3667,7 +3682,7 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
169
169
+
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
170
170
+
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
171
171
+
172
172
+
- if(kex_agree_instr(comp, comp_len, s, method_len)) {
173
173
+
+ if(_libssh2_kex_agree_instr(comp, comp_len, s, method_len)) {
174
174
+
const LIBSSH2_COMP_METHOD *method =
175
175
+
(const LIBSSH2_COMP_METHOD *)
176
176
+
kex_get_method_by_name((char *) s, method_len,
177
177
+
@@ -3689,8 +3704,9 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
178
178
+
}
179
179
+
180
180
+
while(*compp && (*compp)->name) {
181
181
+
- s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
182
182
+
- strlen((*compp)->name));
183
183
+
+ s = _libssh2_kex_agree_instr(comp, comp_len,
184
184
+
+ (unsigned char *) (*compp)->name,
185
185
+
+ strlen((*compp)->name));
186
186
+
if(s) {
187
187
+
endpoint->comp = *compp;
188
188
+
return 0;
189
189
+
@@ -3871,6 +3887,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
190
190
+
session->local.kexinit = key_state->oldlocal;
191
191
+
session->local.kexinit_len = key_state->oldlocal_len;
192
192
+
key_state->state = libssh2_NB_state_idle;
193
193
+
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
194
194
+
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
195
195
+
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
196
196
+
return -1;
197
197
+
@@ -3896,6 +3913,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
198
198
+
session->local.kexinit = key_state->oldlocal;
199
199
+
session->local.kexinit_len = key_state->oldlocal_len;
200
200
+
key_state->state = libssh2_NB_state_idle;
201
201
+
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
202
202
+
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
203
203
+
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
204
204
+
return -1;
205
205
+
@@ -3944,6 +3962,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
206
206
+
session->remote.kexinit = NULL;
207
207
+
}
208
208
+
209
209
+
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
210
210
+
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
211
211
+
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
212
212
+
213
213
+
diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
214
214
+
index 7660366954..18d9ab2130 100644
215
215
+
--- a/src/libssh2_priv.h
216
216
+
+++ b/src/libssh2_priv.h
217
217
+
@@ -736,6 +736,9 @@ struct _LIBSSH2_SESSION
218
218
+
/* key signing algorithm preferences -- NULL yields server order */
219
219
+
char *sign_algo_prefs;
220
220
+
221
221
+
+ /* Whether to use the OpenSSH Strict KEX extension */
222
222
+
+ int kex_strict;
223
223
+
+
224
224
+
/* (remote as source of data -- packet_read ) */
225
225
+
libssh2_endpoint_data remote;
226
226
+
227
227
+
@@ -908,6 +911,7 @@ struct _LIBSSH2_SESSION
228
228
+
int fullpacket_macstate;
229
229
+
size_t fullpacket_payload_len;
230
230
+
int fullpacket_packet_type;
231
231
+
+ uint32_t fullpacket_required_type;
232
232
+
233
233
+
/* State variables used in libssh2_sftp_init() */
234
234
+
libssh2_nonblocking_states sftpInit_state;
235
235
+
@@ -948,10 +952,11 @@ struct _LIBSSH2_SESSION
236
236
+
};
237
237
+
238
238
+
/* session.state bits */
239
239
+
-#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
240
240
+
-#define LIBSSH2_STATE_NEWKEYS 0x00000002
241
241
+
-#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
242
242
+
-#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
243
243
+
+#define LIBSSH2_STATE_INITIAL_KEX 0x00000001
244
244
+
+#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000002
245
245
+
+#define LIBSSH2_STATE_NEWKEYS 0x00000004
246
246
+
+#define LIBSSH2_STATE_AUTHENTICATED 0x00000008
247
247
+
+#define LIBSSH2_STATE_KEX_ACTIVE 0x00000010
248
248
+
249
249
+
/* session.flag helpers */
250
250
+
#ifdef MSG_NOSIGNAL
251
251
+
@@ -1182,6 +1187,11 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
252
252
+
int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
253
253
+
key_exchange_state_t * state);
254
254
+
255
255
+
+unsigned char *_libssh2_kex_agree_instr(unsigned char *haystack,
256
256
+
+ size_t haystack_len,
257
257
+
+ const unsigned char *needle,
258
258
+
+ size_t needle_len);
259
259
+
+
260
260
+
/* Let crypt.c/hostkey.c expose their method structs */
261
261
+
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
262
262
+
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
263
263
+
diff --git a/src/packet.c b/src/packet.c
264
264
+
index eccb8c56a8..6da14e9fa1 100644
265
265
+
--- a/src/packet.c
266
266
+
+++ b/src/packet.c
267
267
+
@@ -624,14 +624,13 @@ packet_authagent_open(LIBSSH2_SESSION * session,
268
268
+
* layer when it has received a packet.
269
269
+
*
270
270
+
* The input pointer 'data' is pointing to allocated data that this function
271
271
+
- * is asked to deal with so on failure OR success, it must be freed fine.
272
272
+
- * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
273
273
+
+ * will be freed unless return the code is LIBSSH2_ERROR_EAGAIN.
274
274
+
*
275
275
+
* This function will always be called with 'datalen' greater than zero.
276
276
+
*/
277
277
+
int
278
278
+
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
279
279
+
- size_t datalen, int macstate)
280
280
+
+ size_t datalen, int macstate, uint32_t seq)
281
281
+
{
282
282
+
int rc = 0;
283
283
+
unsigned char *message = NULL;
284
284
+
@@ -676,6 +675,70 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
285
285
+
break;
286
286
+
}
287
287
+
288
288
+
+ if(session->state & LIBSSH2_STATE_INITIAL_KEX) {
289
289
+
+ if(msg == SSH_MSG_KEXINIT) {
290
290
+
+ if(!session->kex_strict) {
291
291
+
+ if(datalen < 17) {
292
292
+
+ LIBSSH2_FREE(session, data);
293
293
+
+ session->packAdd_state = libssh2_NB_state_idle;
294
294
+
+ return _libssh2_error(session,
295
295
+
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
296
296
+
+ "Data too short extracting kex");
297
297
+
+ }
298
298
+
+ else {
299
299
+
+ const unsigned char *strict =
300
300
+
+ (unsigned char *)"kex-strict-s-v00@openssh.com";
301
301
+
+ struct string_buf buf;
302
302
+
+ unsigned char *algs = NULL;
303
303
+
+ size_t algs_len = 0;
304
304
+
+
305
305
+
+ buf.data = (unsigned char *)data;
306
306
+
+ buf.dataptr = buf.data;
307
307
+
+ buf.len = datalen;
308
308
+
+ buf.dataptr += 17; /* advance past type and cookie */
309
309
+
+
310
310
+
+ if(_libssh2_get_string(&buf, &algs, &algs_len)) {
311
311
+
+ LIBSSH2_FREE(session, data);
312
312
+
+ session->packAdd_state = libssh2_NB_state_idle;
313
313
+
+ return _libssh2_error(session,
314
314
+
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
315
315
+
+ "Algs too short");
316
316
+
+ }
317
317
+
+
318
318
+
+ if(algs_len == 0 ||
319
319
+
+ _libssh2_kex_agree_instr(algs, algs_len, strict, 28)) {
320
320
+
+ session->kex_strict = 1;
321
321
+
+ }
322
322
+
+ }
323
323
+
+ }
324
324
+
+
325
325
+
+ if(session->kex_strict && seq) {
326
326
+
+ LIBSSH2_FREE(session, data);
327
327
+
+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
328
328
+
+ session->packAdd_state = libssh2_NB_state_idle;
329
329
+
+ libssh2_session_disconnect(session, "strict KEX violation: "
330
330
+
+ "KEXINIT was not the first packet");
331
331
+
+
332
332
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
333
333
+
+ "strict KEX violation: "
334
334
+
+ "KEXINIT was not the first packet");
335
335
+
+ }
336
336
+
+ }
337
337
+
+
338
338
+
+ if(session->kex_strict && session->fullpacket_required_type &&
339
339
+
+ session->fullpacket_required_type != msg) {
340
340
+
+ LIBSSH2_FREE(session, data);
341
341
+
+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
342
342
+
+ session->packAdd_state = libssh2_NB_state_idle;
343
343
+
+ libssh2_session_disconnect(session, "strict KEX violation: "
344
344
+
+ "unexpected packet type");
345
345
+
+
346
346
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
347
347
+
+ "strict KEX violation: "
348
348
+
+ "unexpected packet type");
349
349
+
+ }
350
350
+
+ }
351
351
+
+
352
352
+
if(session->packAdd_state == libssh2_NB_state_allocated) {
353
353
+
/* A couple exceptions to the packet adding rule: */
354
354
+
switch(msg) {
355
355
+
@@ -1364,6 +1427,15 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
356
356
+
357
357
+
return 0;
358
358
+
}
359
359
+
+ else if(session->kex_strict &&
360
360
+
+ (session->state & LIBSSH2_STATE_INITIAL_KEX)) {
361
361
+
+ libssh2_session_disconnect(session, "strict KEX violation: "
362
362
+
+ "unexpected packet type");
363
363
+
+
364
364
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
365
365
+
+ "strict KEX violation: "
366
366
+
+ "unexpected packet type");
367
367
+
+ }
368
368
+
packet = _libssh2_list_next(&packet->node);
369
369
+
}
370
370
+
return -1;
371
371
+
@@ -1425,7 +1497,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
372
372
+
}
373
373
+
374
374
+
while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
375
375
+
- int ret = _libssh2_transport_read(session);
376
376
+
+ int ret;
377
377
+
+ session->fullpacket_required_type = packet_type;
378
378
+
+ ret = _libssh2_transport_read(session);
379
379
+
+ session->fullpacket_required_type = 0;
380
380
+
if(ret == LIBSSH2_ERROR_EAGAIN)
381
381
+
return ret;
382
382
+
else if(ret < 0) {
383
383
+
diff --git a/src/packet.h b/src/packet.h
384
384
+
index 1d90b8af12..955351e5f6 100644
385
385
+
--- a/src/packet.h
386
386
+
+++ b/src/packet.h
387
387
+
@@ -72,6 +72,6 @@ int _libssh2_packet_burn(LIBSSH2_SESSION * session,
388
388
+
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
389
389
+
unsigned long data_len);
390
390
+
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
391
391
+
- size_t datalen, int macstate);
392
392
+
+ size_t datalen, int macstate, uint32_t seq);
393
393
+
394
394
+
#endif /* LIBSSH2_PACKET_H */
395
395
+
diff --git a/src/session.c b/src/session.c
396
396
+
index 35e7929fe7..9d89ade8ec 100644
397
397
+
--- a/src/session.c
398
398
+
+++ b/src/session.c
399
399
+
@@ -469,6 +469,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
400
400
+
session->abstract = abstract;
401
401
+
session->api_timeout = 0; /* timeout-free API by default */
402
402
+
session->api_block_mode = 1; /* blocking API by default */
403
403
+
+ session->state = LIBSSH2_STATE_INITIAL_KEX;
404
404
+
+ session->fullpacket_required_type = 0;
405
405
+
session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
406
406
+
session->flag.quote_paths = 1; /* default behavior is to quote paths
407
407
+
for the scp subsystem */
408
408
+
@@ -1223,6 +1225,7 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
409
409
+
const char *desc, const char *lang)
410
410
+
{
411
411
+
int rc;
412
412
+
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
413
413
+
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
414
414
+
BLOCK_ADJUST(rc, session,
415
415
+
session_disconnect(session, reason, desc, lang));
416
416
+
diff --git a/src/transport.c b/src/transport.c
417
417
+
index 21be9d2b80..a8bb588a4b 100644
418
418
+
--- a/src/transport.c
419
419
+
+++ b/src/transport.c
420
420
+
@@ -186,6 +186,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
421
421
+
struct transportpacket *p = &session->packet;
422
422
+
int rc;
423
423
+
int compressed;
424
424
+
+ uint32_t seq = session->remote.seqno;
425
425
+
426
426
+
if(session->fullpacket_state == libssh2_NB_state_idle) {
427
427
+
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
428
428
+
@@ -317,7 +318,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
429
429
+
if(session->fullpacket_state == libssh2_NB_state_created) {
430
430
+
rc = _libssh2_packet_add(session, p->payload,
431
431
+
session->fullpacket_payload_len,
432
432
+
- session->fullpacket_macstate);
433
433
+
+ session->fullpacket_macstate, seq);
434
434
+
if(rc == LIBSSH2_ERROR_EAGAIN)
435
435
+
return rc;
436
436
+
if(rc) {
437
437
+
@@ -328,6 +329,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
438
438
+
439
439
+
session->fullpacket_state = libssh2_NB_state_idle;
440
440
+
441
441
+
+ if(session->kex_strict &&
442
442
+
+ session->fullpacket_packet_type == SSH_MSG_NEWKEYS) {
443
443
+
+ session->remote.seqno = 0;
444
444
+
+ }
445
445
+
+
446
446
+
return session->fullpacket_packet_type;
447
447
+
}
448
448
+
449
449
+
@@ -1093,6 +1099,10 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
450
450
+
451
451
+
session->local.seqno++;
452
452
+
453
453
+
+ if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) {
454
454
+
+ session->local.seqno = 0;
455
455
+
+ }
456
456
+
+
457
457
+
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
458
458
+
LIBSSH2_SOCKET_SEND_FLAGS(session));
459
459
+
if(ret < 0)
+6
pkgs/development/libraries/libssh2/default.nix
reviewed
···
9
9
sha256 = "sha256-NzYWHkHiaTMk3rOMJs/cPv5iCdY0ukJY2xzs/2pa1GE=";
10
10
};
11
11
12
12
+
patches = [
13
13
+
# fetchpatch cannot be used due to infinite recursion
14
14
+
# https://github.com/libssh2/libssh2/commit/d34d9258b8420b19ec3f97b4cc5bf7aa7d98e35a
15
15
+
./CVE-2023-48795.patch
16
16
+
];
17
17
+
12
18
outputs = [ "out" "dev" "devdoc" ];
13
19
14
20
propagatedBuildInputs = [ openssl ]; # see Libs: in libssh2.pc