/src/libssh2/src/transport.c
Line | Count | Source |
1 | | /* Copyright (C) The Written Word, Inc. |
2 | | * Copyright (C) Daniel Stenberg |
3 | | * All rights reserved. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions are met: |
7 | | * |
8 | | * 1. Redistributions of source code must retain the above copyright notice, |
9 | | * this list of conditions and the following disclaimer. |
10 | | * |
11 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
12 | | * this list of conditions and the following disclaimer in the documentation |
13 | | * and/or other materials provided with the distribution. |
14 | | * |
15 | | * 3. Neither the name of the copyright holder nor the names of its |
16 | | * contributors may be used to endorse or promote products derived from this |
17 | | * software without specific prior written permission. |
18 | | * |
19 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
23 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | | * POSSIBILITY OF SUCH DAMAGE. |
30 | | * |
31 | | * SPDX-License-Identifier: BSD-3-Clause |
32 | | */ |
33 | | |
34 | | /* |
35 | | * This file handles reading and writing to the SECSH transport layer. RFC4253. |
36 | | */ |
37 | | |
38 | | #include "libssh2_priv.h" |
39 | | |
40 | | #include <ctype.h> |
41 | | #include <assert.h> |
42 | | |
43 | | #include "transport.h" |
44 | | #include "mac.h" |
45 | | |
46 | | #ifdef LIBSSH2DEBUG |
47 | 0 | #define UNPRINTABLE_CHAR '.' |
48 | | static void transport_debugdump(LIBSSH2_SESSION *session, const char *desc, |
49 | | const unsigned char *ptr, size_t size) |
50 | 132k | { |
51 | 132k | size_t i; |
52 | 132k | size_t c; |
53 | 132k | unsigned int width = 0x10; |
54 | 132k | char buffer[256]; /* Must be enough for width*4 + about 30 or so */ |
55 | 132k | size_t used; |
56 | 132k | static const char *hex_chars = "0123456789ABCDEF"; |
57 | | |
58 | 132k | if(!(session->showmask & LIBSSH2_TRACE_TRANS)) |
59 | 132k | return; /* not asked for, bail out */ |
60 | | |
61 | 0 | used = ssh2_snprintf(buffer, sizeof(buffer), "=> %s (%lu bytes)\n", |
62 | 0 | desc, (unsigned long)size); |
63 | 0 | if(session->tracehandler) |
64 | 0 | (session->tracehandler)(session, session->tracehandler_context, |
65 | 0 | buffer, used); |
66 | 0 | else |
67 | | /* !checksrc! disable BANNEDFUNC 1 */ |
68 | 0 | fprintf(stderr, "%s", buffer); |
69 | |
|
70 | 0 | for(i = 0; i < size; i += width) { |
71 | |
|
72 | 0 | used = ssh2_snprintf(buffer, sizeof(buffer), "%04lx: ", |
73 | 0 | (unsigned long)i); |
74 | | |
75 | | /* hex not disabled, show it */ |
76 | 0 | for(c = 0; c < width; c++) { |
77 | 0 | if(i + c < size) { |
78 | 0 | buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF]; |
79 | 0 | buffer[used++] = hex_chars[ptr[i + c] & 0xF]; |
80 | 0 | } |
81 | 0 | else { |
82 | 0 | buffer[used++] = ' '; |
83 | 0 | buffer[used++] = ' '; |
84 | 0 | } |
85 | |
|
86 | 0 | buffer[used++] = ' '; |
87 | 0 | if((width / 2) - 1 == c) |
88 | 0 | buffer[used++] = ' '; |
89 | 0 | } |
90 | |
|
91 | 0 | buffer[used++] = ':'; |
92 | 0 | buffer[used++] = ' '; |
93 | |
|
94 | 0 | for(c = 0; c < width && (i + c) < size; c++) { |
95 | 0 | buffer[used++] = isprint(ptr[i + c]) ? |
96 | 0 | ptr[i + c] : UNPRINTABLE_CHAR; |
97 | 0 | } |
98 | 0 | buffer[used] = 0; |
99 | |
|
100 | 0 | if(session->tracehandler) |
101 | 0 | (session->tracehandler)(session, session->tracehandler_context, |
102 | 0 | buffer, used); |
103 | 0 | else |
104 | | /* !checksrc! disable BANNEDFUNC 1 */ |
105 | 0 | fprintf(stderr, "%s\n", buffer); |
106 | 0 | } |
107 | 0 | } |
108 | | #else |
109 | | #define transport_debugdump(a, x, y, z) do {} while(0) |
110 | | #endif |
111 | | |
112 | | /* transport_decrypt() decrypts 'len' bytes from 'source' to 'dest' in units of |
113 | | * blocksize. |
114 | | * |
115 | | * returns 0 on success and negative on failure |
116 | | */ |
117 | | static int transport_decrypt(LIBSSH2_SESSION *session, unsigned char *source, |
118 | | unsigned char *dest, ssize_t len, int firstlast) |
119 | 0 | { |
120 | 0 | struct transportpacket *p = &session->packet; |
121 | 0 | int blocksize = session->remote.crypt->blocksize; |
122 | | |
123 | | /* if we get called with a len that is not an even number of blocksizes |
124 | | we risk losing those extra bytes. AAD is an exception, since those first |
125 | | few bytes are not encrypted so it throws off the rest of the count. */ |
126 | 0 | if(!CRYPT_FLAG_R(session, PKTLEN_AAD)) |
127 | 0 | assert((len % blocksize) == 0); |
128 | |
|
129 | 0 | while(len > 0) { |
130 | | /* normally decrypt up to blocksize bytes at a time */ |
131 | 0 | ssize_t decryptlen = SSH2_MIN(blocksize, len); |
132 | | /* The first block is special (since it needs to be decoded to get the |
133 | | length of the remainder of the block) and takes priority. When the |
134 | | length finally gets to the last blocksize bytes, and there is no |
135 | | more data to come, it is the end. */ |
136 | 0 | int lowerfirstlast = IS_FIRST(firstlast) ? FIRST_BLOCK : |
137 | 0 | ((len <= blocksize) ? firstlast : MIDDLE_BLOCK); |
138 | | /* If the last block would be less than a whole blocksize, combine it |
139 | | with the previous block to make it larger. This ensures that the |
140 | | whole MAC is included in a single decrypt call. */ |
141 | 0 | if(CRYPT_FLAG_R(session, PKTLEN_AAD) && IS_LAST(firstlast) && |
142 | 0 | (len < blocksize * 2)) { |
143 | 0 | decryptlen = len; |
144 | 0 | lowerfirstlast = LAST_BLOCK; |
145 | 0 | } |
146 | |
|
147 | 0 | if(session->remote.crypt->crypt(session, 0, source, decryptlen, |
148 | 0 | &session->remote.crypt_abstract, |
149 | 0 | lowerfirstlast)) { |
150 | 0 | SSH2_SAFEFREE(session, p->payload); |
151 | 0 | return LIBSSH2_ERROR_DECRYPT; |
152 | 0 | } |
153 | | |
154 | | /* if the crypt() function would write to a given address it |
155 | | would not have to memcpy() and we could avoid this memcpy() |
156 | | too */ |
157 | 0 | memcpy(dest, source, decryptlen); |
158 | |
|
159 | 0 | len -= decryptlen; /* less bytes left */ |
160 | 0 | dest += decryptlen; /* advance write pointer */ |
161 | 0 | source += decryptlen; /* advance read pointer */ |
162 | 0 | } |
163 | 0 | return LIBSSH2_ERROR_NONE; /* all is fine */ |
164 | 0 | } |
165 | | |
166 | | /* |
167 | | * transport_fullpacket() gets called when a full packet has been received and |
168 | | * properly collected. |
169 | | */ |
170 | | static int transport_fullpacket(LIBSSH2_SESSION *session, |
171 | | int encrypted /* 1 or 0 */) |
172 | 86.7k | { |
173 | 86.7k | unsigned char macbuf[MAX_MACSIZE]; |
174 | 86.7k | struct transportpacket *p = &session->packet; |
175 | 86.7k | int rc; |
176 | 86.7k | int compressed; |
177 | 86.7k | const struct mac_method *remote_mac = NULL; |
178 | 86.7k | uint32_t seq = session->remote.seqno; |
179 | | |
180 | 86.7k | memset(macbuf, '\0', sizeof(macbuf)); |
181 | | |
182 | 86.7k | if(!encrypted || (!CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET) && |
183 | 0 | !CRYPT_FLAG_R(session, INTEGRATED_MAC))) |
184 | 86.7k | remote_mac = session->remote.mac; |
185 | | |
186 | 86.7k | if(session->fullpacket_state == ssh2_NB_state_idle) { |
187 | 86.7k | session->fullpacket_macstate = SSH2_MAC_CONFIRMED; |
188 | 86.7k | session->fullpacket_payload_len = p->packet_length - 1; |
189 | | |
190 | 86.7k | if(encrypted && remote_mac) { |
191 | | |
192 | | /* Calculate MAC hash */ |
193 | 0 | int etm = remote_mac->etm; |
194 | 0 | size_t mac_len = remote_mac->mac_len; |
195 | 0 | if(etm) /* store hash here */ |
196 | 0 | remote_mac->hash(session, macbuf, |
197 | 0 | session->remote.seqno, |
198 | 0 | p->payload, p->total_num - mac_len, |
199 | 0 | NULL, 0, |
200 | 0 | &session->remote.mac_abstract); |
201 | 0 | else /* store hash here */ |
202 | 0 | remote_mac->hash(session, macbuf, |
203 | 0 | session->remote.seqno, |
204 | 0 | p->init, 5, |
205 | 0 | p->payload, |
206 | 0 | session->fullpacket_payload_len, |
207 | 0 | &session->remote.mac_abstract); |
208 | | |
209 | | /* Compare the calculated hash with the MAC we read from |
210 | | * the network. The read one is at the end of the payload |
211 | | * buffer. Note that 'payload_len' here is the packet_length |
212 | | * field which includes the padding but not the MAC. |
213 | | */ |
214 | 0 | if(ssh2_timingsafe_bcmp(macbuf, |
215 | 0 | p->payload + p->total_num - mac_len, |
216 | 0 | mac_len)) { |
217 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, "Failed MAC check")); |
218 | 0 | session->fullpacket_macstate = SSH2_MAC_INVALID; |
219 | 0 | } |
220 | 0 | else if(etm) { |
221 | | /* MAC was ok and we start by decrypting the first block that |
222 | | contains padding length since this allows us to decrypt |
223 | | all other blocks to the right location in memory |
224 | | avoiding moving a larger block of memory one byte. */ |
225 | 0 | unsigned char first_block[MAX_BLOCKSIZE]; |
226 | 0 | ssize_t decrypt_size; |
227 | 0 | unsigned char *decrypt_buffer; |
228 | 0 | int blocksize = session->remote.crypt->blocksize; |
229 | |
|
230 | 0 | first_block[0] = 0; |
231 | |
|
232 | 0 | rc = transport_decrypt(session, p->payload + 4, |
233 | 0 | first_block, blocksize, FIRST_BLOCK); |
234 | 0 | if(rc) |
235 | 0 | return rc; |
236 | | |
237 | | /* we need buffer for decrypt */ |
238 | 0 | decrypt_size = p->total_num - mac_len - 4; |
239 | 0 | decrypt_buffer = SSH2_ALLOC(session, decrypt_size); |
240 | 0 | if(!decrypt_buffer) |
241 | 0 | return LIBSSH2_ERROR_ALLOC; |
242 | | |
243 | | /* grab padding length and copy anything else |
244 | | into target buffer */ |
245 | 0 | p->padding_length = first_block[0]; |
246 | |
|
247 | 0 | if(p->padding_length > p->packet_length - 1) { |
248 | 0 | SSH2_FREE(session, decrypt_buffer); |
249 | 0 | return LIBSSH2_ERROR_PROTO; |
250 | 0 | } |
251 | | |
252 | 0 | if(blocksize > 1) |
253 | 0 | memcpy(decrypt_buffer, first_block + 1, blocksize - 1); |
254 | | |
255 | | /* decrypt all other blocks packet */ |
256 | 0 | if(blocksize < decrypt_size) { |
257 | 0 | rc = transport_decrypt(session, |
258 | 0 | p->payload + blocksize + 4, |
259 | 0 | decrypt_buffer + blocksize - 1, |
260 | 0 | decrypt_size - blocksize, |
261 | 0 | LAST_BLOCK); |
262 | 0 | if(rc) { |
263 | 0 | SSH2_FREE(session, decrypt_buffer); |
264 | 0 | return rc; |
265 | 0 | } |
266 | 0 | } |
267 | | |
268 | | /* replace encrypted payload with plain text payload */ |
269 | 0 | SSH2_FREE(session, p->payload); |
270 | 0 | p->payload = decrypt_buffer; |
271 | 0 | } |
272 | 0 | } |
273 | 86.7k | else if(encrypted && CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) |
274 | | /* etm trim off padding byte from payload */ |
275 | 0 | memmove(p->payload, &p->payload[1], p->packet_length - 1); |
276 | | |
277 | 86.7k | session->remote.seqno++; |
278 | | |
279 | | /* ignore the padding */ |
280 | 86.7k | session->fullpacket_payload_len -= p->padding_length; |
281 | | |
282 | | /* Check for and deal with decompression */ |
283 | 86.7k | compressed = session->local.comp && |
284 | 37.5k | session->local.comp->compress && |
285 | 0 | ((session->state & SSH2_STATE_AUTHENTICATED) || |
286 | 0 | session->local.comp->use_in_auth); |
287 | | |
288 | 86.7k | if(compressed && session->remote.comp_abstract) { |
289 | | /* |
290 | | * The buffer for the decompression (remote.comp_abstract) is |
291 | | * initialised in time when it is needed so as long it is NULL we |
292 | | * cannot decompress. |
293 | | */ |
294 | |
|
295 | 0 | unsigned char *data = NULL; |
296 | 0 | size_t data_len = 0; |
297 | 0 | rc = session->remote.comp->decomp(session, |
298 | 0 | &data, &data_len, |
299 | 0 | LIBSSH2_PACKET_MAXDECOMP, |
300 | 0 | p->payload, |
301 | 0 | session->fullpacket_payload_len, |
302 | 0 | &session->remote.comp_abstract); |
303 | 0 | SSH2_SAFEFREE(session, p->payload); |
304 | 0 | if(rc) |
305 | 0 | return rc; |
306 | | |
307 | 0 | p->payload = data; |
308 | 0 | session->fullpacket_payload_len = data_len; |
309 | 0 | } |
310 | | |
311 | 86.7k | session->fullpacket_packet_type = p->payload[0]; |
312 | | |
313 | 86.7k | transport_debugdump(session, "ssh2_transport_read() plain", |
314 | 86.7k | p->payload, session->fullpacket_payload_len); |
315 | | |
316 | 86.7k | session->fullpacket_state = ssh2_NB_state_created; |
317 | 86.7k | } |
318 | | |
319 | 86.7k | if(session->fullpacket_state == ssh2_NB_state_created) { |
320 | 86.7k | rc = ssh2_packet_add(session, p->payload, |
321 | 86.7k | session->fullpacket_payload_len, |
322 | 86.7k | session->fullpacket_macstate, seq); |
323 | 86.7k | if(rc == LIBSSH2_ERROR_EAGAIN) { |
324 | | /* ssh2_packet_add() queues the packet into session->packets before |
325 | | * attempting follow-up work like key re-exchange. If EAGAIN occurs |
326 | | * during that work, packAdd_state is reset to idle and the data is |
327 | | * already owned by the packet queue. Clear p->payload to prevent |
328 | | * double-free in session cleanup. */ |
329 | 0 | if(session->packAdd_state == ssh2_NB_state_idle) |
330 | 0 | p->payload = NULL; |
331 | 0 | return rc; |
332 | 0 | } |
333 | | /* ssh2_packet_add() takes ownership of the payload on all non-EAGAIN |
334 | | * paths, so clear the pointer */ |
335 | 86.7k | p->payload = NULL; |
336 | 86.7k | if(rc) { |
337 | 211 | session->fullpacket_state = ssh2_NB_state_idle; |
338 | 211 | return rc; |
339 | 211 | } |
340 | 86.7k | } |
341 | | |
342 | 86.5k | session->fullpacket_state = ssh2_NB_state_idle; |
343 | | |
344 | 86.5k | if(session->kex_strict && |
345 | 6.61k | session->fullpacket_packet_type == SSH_MSG_NEWKEYS) |
346 | 71 | session->remote.seqno = 0; |
347 | | |
348 | 86.5k | return session->fullpacket_packet_type; |
349 | 86.7k | } |
350 | | |
351 | | /* |
352 | | * Collect a packet into the input queue. |
353 | | * |
354 | | * Returns packet type added to input queue (0 if nothing added), or a |
355 | | * negative error number. |
356 | | * |
357 | | * This function reads the binary stream as specified in chapter 6 of RFC4253 |
358 | | * "The Secure Shell (SSH) Transport Layer Protocol" |
359 | | * |
360 | | * DOES NOT call ssh2_err() for ANY error case. |
361 | | */ |
362 | | int ssh2_transport_read(LIBSSH2_SESSION *session) |
363 | 89.0k | { |
364 | 89.0k | int rc; |
365 | 89.0k | struct transportpacket *p = &session->packet; |
366 | 89.0k | ssize_t remainpack; /* how much there is left to add to the current payload |
367 | | package */ |
368 | 89.0k | ssize_t remainbuf; /* how much data there is remaining in the buffer to |
369 | | deal with before we should read more from the |
370 | | network */ |
371 | 89.0k | ssize_t numbytes; /* how much data to deal with from the buffer on this |
372 | | iteration through the loop */ |
373 | 89.0k | ssize_t numdecrypt; /* number of bytes to decrypt this iteration */ |
374 | 89.0k | unsigned char block[MAX_BLOCKSIZE]; /* working block buffer */ |
375 | 89.0k | int blocksize; /* minimum number of bytes we need before we can |
376 | | use them */ |
377 | 89.0k | int encrypted = 1; /* whether the packet is encrypted or not */ |
378 | 89.0k | int firstlast = FIRST_BLOCK; /* if the first or last block to decrypt */ |
379 | 89.0k | unsigned int auth_len = 0; /* length of the authentication tag */ |
380 | 89.0k | const struct mac_method *remote_mac = NULL; /* The remote MAC, if used */ |
381 | | |
382 | 89.0k | block[4] = 0; |
383 | | |
384 | | /* default clear the bit */ |
385 | 89.0k | session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; |
386 | | |
387 | | /* |
388 | | * All channels, systems, subsystems, etc eventually make it down here |
389 | | * when looking for more incoming data. If a key exchange is going on |
390 | | * (SSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end |
391 | | * ONLY sends key exchange related traffic. In non-blocking mode, there is |
392 | | * a chance to break out of the kex_exchange function with an EAGAIN |
393 | | * status, and never come back to it. If SSH2_STATE_EXCHANGING_KEYS is |
394 | | * active, then we must redirect to the key exchange. However, if |
395 | | * kex_exchange is active (as in it is the one that calls this execution |
396 | | * of packet_read, then do not redirect, as that would be an infinite loop! |
397 | | */ |
398 | | |
399 | 89.0k | if(session->state & SSH2_STATE_EXCHANGING_KEYS && |
400 | 56.6k | !(session->state & SSH2_STATE_KEX_ACTIVE)) { |
401 | | |
402 | | /* Whoever wants a packet does not get anything until the key |
403 | | * re-exchange is done! |
404 | | */ |
405 | 0 | ssh2_deb((session, LIBSSH2_TRACE_TRANS, "Redirecting into the" |
406 | 0 | " key re-exchange from ssh2_transport_read()")); |
407 | 0 | rc = ssh2_kex_exchange(session, 1, &session->startup_key_state); |
408 | 0 | if(rc) |
409 | 0 | return rc; |
410 | 0 | } |
411 | | |
412 | | /* |
413 | | * =============================== NOTE =============================== |
414 | | * I know this is ugly and not a really good use of "goto", but |
415 | | * this case statement would be even uglier to do it any other way |
416 | | */ |
417 | 89.0k | if(session->readPack_state == ssh2_NB_state_jump1) { |
418 | 0 | session->readPack_state = ssh2_NB_state_idle; |
419 | 0 | encrypted = session->readPack_encrypted; |
420 | 0 | goto ssh2_transport_read_point1; |
421 | 0 | } |
422 | | |
423 | 89.4k | do { |
424 | 89.4k | int etm; |
425 | 89.4k | if(session->socket_state == SSH2_SOCKET_DISCONNECTED) |
426 | 0 | return LIBSSH2_ERROR_SOCKET_DISCONNECT; |
427 | | |
428 | 89.4k | if(session->state & SSH2_STATE_NEWKEYS) |
429 | 0 | blocksize = session->remote.crypt->blocksize; |
430 | 89.4k | else { |
431 | 89.4k | encrypted = 0; /* not encrypted */ |
432 | 89.4k | blocksize = 5; /* not strictly true, but we can use 5 here to |
433 | | make the checks below work fine still */ |
434 | 89.4k | } |
435 | | |
436 | 89.4k | if(encrypted) { |
437 | 0 | if(CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) |
438 | 0 | auth_len = session->remote.crypt->auth_len; |
439 | 0 | else |
440 | 0 | remote_mac = session->remote.mac; |
441 | 0 | } |
442 | | |
443 | 89.4k | etm = encrypted && remote_mac ? remote_mac->etm : 0; |
444 | | |
445 | | /* read/use a whole big chunk into a temporary area stored in |
446 | | the LIBSSH2_SESSION struct. We decrypt data from that |
447 | | buffer into the packet buffer so this temp one does not have |
448 | | to be able to keep a whole SSH packet, be large enough |
449 | | so that we can read big chunks from the network layer. */ |
450 | | |
451 | | /* how much data there is remaining in the buffer to deal with |
452 | | before we should read more from the network */ |
453 | 89.4k | remainbuf = p->writeidx - p->readidx; |
454 | | |
455 | | /* if remainbuf turns negative we have a bad internal error */ |
456 | 89.4k | assert(remainbuf >= 0); |
457 | | |
458 | 89.4k | if(remainbuf < blocksize || |
459 | 84.4k | (CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET) && |
460 | 5.06k | ((ssize_t)p->total_num) > remainbuf)) { |
461 | | /* If we have less than a blocksize left, it is too |
462 | | little data to deal with, read more */ |
463 | 5.06k | ssize_t nread; |
464 | | |
465 | | /* move any remainder to the start of the buffer so |
466 | | that we can do a full refill */ |
467 | 5.06k | if(remainbuf) { |
468 | 259 | memmove(p->buf, &p->buf[p->readidx], remainbuf); |
469 | 259 | p->readidx = 0; |
470 | 259 | p->writeidx = remainbuf; |
471 | 259 | } |
472 | 4.80k | else /* nothing to move, zero the indexes */ |
473 | 4.80k | p->readidx = p->writeidx = 0; |
474 | | |
475 | | /* now read a big chunk from the network into the temp buffer */ |
476 | 5.06k | nread = SSH2_RECV(session, &p->buf[remainbuf], |
477 | 5.06k | PACKETBUFSIZE - remainbuf, |
478 | 5.06k | SSH2_SOCKET_RECV_FLAGS(session)); |
479 | 5.06k | if(nread <= 0) { |
480 | | /* check if this is due to EAGAIN and return the special |
481 | | return code if so, error out normally otherwise */ |
482 | 1.37k | if(nread < 0 && nread == -EAGAIN) { |
483 | 0 | session->socket_block_directions |= |
484 | 0 | LIBSSH2_SESSION_BLOCK_INBOUND; |
485 | 0 | return LIBSSH2_ERROR_EAGAIN; |
486 | 0 | } |
487 | 1.37k | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
488 | 1.37k | "Error recving %ld bytes (got %ld)", |
489 | 1.37k | (long)(PACKETBUFSIZE - remainbuf), (long)-nread)); |
490 | 1.37k | return LIBSSH2_ERROR_SOCKET_RECV; |
491 | 1.37k | } |
492 | 3.68k | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
493 | 3.68k | "Recved %ld/%ld bytes to %p+%ld", (long)nread, |
494 | 3.68k | (long)(PACKETBUFSIZE - remainbuf), (void *)p->buf, |
495 | 3.68k | (long)remainbuf)); |
496 | | |
497 | 3.68k | transport_debugdump(session, "ssh2_transport_read() raw", |
498 | 3.68k | &p->buf[remainbuf], nread); |
499 | | /* advance write pointer */ |
500 | 3.68k | p->writeidx += nread; |
501 | | |
502 | | /* update remainbuf counter */ |
503 | 3.68k | remainbuf = p->writeidx - p->readidx; |
504 | 3.68k | } |
505 | | |
506 | | /* how much data to deal with from the buffer */ |
507 | 88.1k | numbytes = remainbuf; |
508 | | |
509 | 88.1k | if(!p->total_num) { |
510 | 88.0k | size_t total_num; /* the number of bytes following the initial |
511 | | (5 bytes) packet length and padding length |
512 | | fields */ |
513 | | |
514 | | /* packet length is not encrypted in encode-then-mac mode |
515 | | and we do not need to decrypt first block */ |
516 | 88.0k | ssize_t required_size = etm ? 4 : blocksize; |
517 | | |
518 | | /* No payload package area allocated yet. To know the |
519 | | size of this payload, we need enough to decrypt the first |
520 | | blocksize data. */ |
521 | | |
522 | 88.0k | if(numbytes < required_size) { |
523 | | /* we cannot act on anything less than blocksize, but this |
524 | | check is only done for the initial block since once we have |
525 | | got the start of a block we can in fact deal with fractions |
526 | | */ |
527 | 10 | session->socket_block_directions |= |
528 | 10 | LIBSSH2_SESSION_BLOCK_INBOUND; |
529 | 10 | return LIBSSH2_ERROR_EAGAIN; |
530 | 10 | } |
531 | | |
532 | 88.0k | if(etm) { |
533 | | /* etm size field is not encrypted */ |
534 | 0 | memcpy(block, &p->buf[p->readidx], 4); |
535 | 0 | memcpy(p->init, &p->buf[p->readidx], 4); |
536 | 0 | } |
537 | 88.0k | else if(encrypted && session->remote.crypt->get_len) { |
538 | 0 | unsigned int len = 0; |
539 | 0 | unsigned char *ptr = NULL; |
540 | |
|
541 | 0 | rc = session->remote.crypt->get_len(session, |
542 | 0 | session->remote.seqno, |
543 | 0 | &p->buf[p->readidx], |
544 | 0 | numbytes, |
545 | 0 | &len, |
546 | 0 | &session->remote.crypt_abstract); |
547 | |
|
548 | 0 | if(rc != LIBSSH2_ERROR_NONE) { |
549 | 0 | p->total_num = 0; /* no packet buffer available */ |
550 | 0 | if(p->payload) |
551 | 0 | SSH2_SAFEFREE(session, p->payload); |
552 | 0 | return rc; |
553 | 0 | } |
554 | | |
555 | | /* store size in buffers for use below */ |
556 | 0 | ptr = &block[0]; |
557 | 0 | ssh2_store_u32(&ptr, len); |
558 | |
|
559 | 0 | ptr = &p->init[0]; |
560 | 0 | ssh2_store_u32(&ptr, len); |
561 | 0 | } |
562 | 88.0k | else { |
563 | 88.0k | if(encrypted) { |
564 | | /* first decrypted block */ |
565 | 0 | rc = transport_decrypt(session, &p->buf[p->readidx], |
566 | 0 | block, blocksize, FIRST_BLOCK); |
567 | 0 | if(rc != LIBSSH2_ERROR_NONE) |
568 | 0 | return rc; |
569 | | /* Save the first 5 bytes of the decrypted package, to be |
570 | | used in the hash calculation later down. |
571 | | This is ignored in the INTEGRATED_MAC case. */ |
572 | 0 | memcpy(p->init, block, 5); |
573 | 0 | } |
574 | 88.0k | else { |
575 | | /* the data is plain, copy it verbatim to |
576 | | the working block buffer */ |
577 | 88.0k | memcpy(block, &p->buf[p->readidx], blocksize); |
578 | 88.0k | } |
579 | | |
580 | | /* advance the read pointer */ |
581 | 88.0k | p->readidx += blocksize; |
582 | | |
583 | | /* we now have the initial blocksize bytes decrypted, |
584 | | * and we can extract packet and padding length from it |
585 | | */ |
586 | 88.0k | p->packet_length = ssh2_ntohu32(block); |
587 | 88.0k | } |
588 | | |
589 | 88.0k | if(!encrypted || !CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) { |
590 | 88.0k | if(p->packet_length < 1) |
591 | 94 | return LIBSSH2_ERROR_DECRYPT; |
592 | 87.9k | else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) |
593 | 726 | return LIBSSH2_ERROR_OUT_OF_BOUNDARY; |
594 | | |
595 | 87.2k | if(etm) { |
596 | | /* do not know what padding is until we decrypt the full |
597 | | packet */ |
598 | 0 | p->padding_length = 0; |
599 | | |
600 | | /* we collect entire undecrypted packet including the |
601 | | packet length field that we run MAC over */ |
602 | 0 | p->packet_length = ssh2_ntohu32(block); |
603 | 0 | total_num = 4 + p->packet_length + remote_mac->mac_len; |
604 | 0 | } |
605 | 87.2k | else { |
606 | | /* padding_length has not been authenticated yet, but it |
607 | | is not actually used (except for the sanity check |
608 | | immediately following) until after the entire packet is |
609 | | authenticated, so this is safe. */ |
610 | 87.2k | p->padding_length = block[4]; |
611 | 87.2k | if(p->padding_length > p->packet_length - 1) |
612 | 135 | return LIBSSH2_ERROR_DECRYPT; |
613 | | |
614 | | /* total_num is the number of bytes following the initial |
615 | | (5 bytes) packet length and padding length fields */ |
616 | 87.1k | total_num = p->packet_length - 1 + |
617 | 87.1k | (encrypted && remote_mac ? remote_mac->mac_len : 0); |
618 | 87.1k | } |
619 | 87.2k | } |
620 | 0 | else { |
621 | | /* advance the read pointer past size field if the packet |
622 | | length is not required for decryption */ |
623 | | |
624 | | /* add size field to be included in total packet size |
625 | | * calculation so it does not get dropped off on subsequent |
626 | | * partial reads |
627 | | */ |
628 | 0 | total_num = 4; |
629 | |
|
630 | 0 | p->packet_length = ssh2_ntohu32(block); |
631 | 0 | if(p->packet_length < 1) |
632 | 0 | return LIBSSH2_ERROR_DECRYPT; |
633 | 0 | else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) |
634 | 0 | return LIBSSH2_ERROR_OUT_OF_BOUNDARY; |
635 | | |
636 | | /* total_num may include size field, however due to existing |
637 | | * logic it needs to be removed after the entire packet is read |
638 | | */ |
639 | | |
640 | 0 | total_num += p->packet_length + |
641 | 0 | (remote_mac ? remote_mac->mac_len : 0) + auth_len; |
642 | | |
643 | | /* do not know what padding is until we decrypt the full |
644 | | packet */ |
645 | 0 | p->padding_length = 0; |
646 | 0 | } |
647 | | |
648 | | /* RFC4253 section 6.1 Maximum Packet Length says: |
649 | | * |
650 | | * "All implementations MUST be able to process |
651 | | * packets with uncompressed payload length of 32768 |
652 | | * bytes or less and total packet size of 35000 bytes |
653 | | * or less (including length, padding length, payload, |
654 | | * padding, and MAC.)." |
655 | | */ |
656 | 87.1k | if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) |
657 | 6 | return LIBSSH2_ERROR_OUT_OF_BOUNDARY; |
658 | | |
659 | | /* Get a packet handle put data into. We get one to |
660 | | hold all data, including padding and MAC. */ |
661 | 87.1k | p->payload = SSH2_ALLOC(session, total_num); |
662 | 87.1k | if(!p->payload) |
663 | 0 | return LIBSSH2_ERROR_ALLOC; |
664 | 87.1k | p->total_num = total_num; |
665 | | /* init write pointer to start of payload buffer */ |
666 | 87.1k | p->wptr = p->payload; |
667 | | |
668 | 87.1k | if(!encrypted || !CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) { |
669 | 87.1k | if(!etm && blocksize > 5) { |
670 | | /* copy the data from index 5 to the end of |
671 | | the blocksize from the temporary buffer to |
672 | | the start of the decrypted buffer */ |
673 | 0 | if(blocksize - 5 <= (int)total_num) { |
674 | 0 | memcpy(p->wptr, &block[5], blocksize - 5); |
675 | 0 | p->wptr += blocksize - 5; /* advance write pointer */ |
676 | 0 | } |
677 | 0 | else { |
678 | 0 | if(p->payload) |
679 | 0 | SSH2_SAFEFREE(session, p->payload); |
680 | 0 | return LIBSSH2_ERROR_OUT_OF_BOUNDARY; |
681 | 0 | } |
682 | 0 | } |
683 | | |
684 | | /* init the data_num field to the number of bytes of |
685 | | the package read so far */ |
686 | 87.1k | p->data_num = p->wptr - p->payload; |
687 | | |
688 | | /* we already dealt with a blocksize worth of data */ |
689 | 87.1k | if(!etm) |
690 | 87.1k | numbytes -= blocksize; |
691 | 87.1k | } |
692 | 0 | else { |
693 | | /* have not started reading payload yet */ |
694 | 0 | p->data_num = 0; |
695 | | |
696 | | /* we already dealt with packet size worth of data */ |
697 | 0 | if(!encrypted) |
698 | 0 | numbytes -= 4; |
699 | 0 | } |
700 | 87.1k | } |
701 | | |
702 | | /* how much there is left to add to the current payload |
703 | | package */ |
704 | 87.1k | remainpack = p->total_num - p->data_num; |
705 | | |
706 | 87.1k | if(numbytes > remainpack) |
707 | | /* if we have more data in the buffer than what is going into this |
708 | | particular packet, we limit this round to this packet only */ |
709 | 85.4k | numbytes = remainpack; |
710 | | |
711 | 87.1k | if(encrypted && CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) { |
712 | 0 | if(numbytes < remainpack) { |
713 | | /* need a full packet before checking MAC */ |
714 | 0 | session->socket_block_directions |= |
715 | 0 | LIBSSH2_SESSION_BLOCK_INBOUND; |
716 | 0 | return LIBSSH2_ERROR_EAGAIN; |
717 | 0 | } |
718 | | |
719 | | /* we have a full packet, now remove the size field from numbytes |
720 | | and total_num to process only the packet data */ |
721 | 0 | numbytes -= 4; |
722 | 0 | p->total_num -= 4; |
723 | 0 | } |
724 | | |
725 | 87.1k | if(encrypted && !etm) { |
726 | | /* At the end of the incoming stream, there is a MAC, |
727 | | and we do not want to decrypt that since we need it |
728 | | "raw". We MUST however decrypt the padding data |
729 | | since it is used for the hash later on. */ |
730 | 0 | int skip = (remote_mac ? remote_mac->mac_len : 0) + auth_len; |
731 | |
|
732 | 0 | if(CRYPT_FLAG_R(session, INTEGRATED_MAC)) |
733 | | /* This crypto method DOES need the MAC to go through |
734 | | decryption so it can be authenticated. */ |
735 | 0 | skip = 0; |
736 | | |
737 | | /* if what we have plus numbytes is bigger than the |
738 | | total minus the skip margin, we should lower the |
739 | | amount to decrypt even more */ |
740 | 0 | if((p->data_num + numbytes) >= (p->total_num - skip)) { |
741 | | /* decrypt the entire rest of the package */ |
742 | 0 | numdecrypt = SSH2_MAX(0, |
743 | 0 | (int)(p->total_num - skip) - (int)p->data_num); |
744 | 0 | firstlast = LAST_BLOCK; |
745 | 0 | } |
746 | 0 | else { |
747 | 0 | ssize_t frac; |
748 | 0 | numdecrypt = numbytes; |
749 | 0 | frac = numdecrypt % blocksize; |
750 | 0 | if(frac) { |
751 | | /* not an aligned amount of blocks, align it by reducing |
752 | | the number of bytes processed this loop */ |
753 | 0 | numdecrypt -= frac; |
754 | | /* and make it no unencrypted data |
755 | | after it */ |
756 | 0 | numbytes = 0; |
757 | 0 | } |
758 | 0 | if(CRYPT_FLAG_R(session, INTEGRATED_MAC)) { |
759 | | /* Make sure that we save enough bytes to make the last |
760 | | * block large enough to hold the entire integrated MAC */ |
761 | 0 | numdecrypt = SSH2_MIN(numdecrypt, |
762 | 0 | (int)(p->total_num - skip - blocksize - p->data_num)); |
763 | 0 | numbytes = 0; |
764 | 0 | } |
765 | 0 | firstlast = MIDDLE_BLOCK; |
766 | 0 | } |
767 | 0 | } |
768 | 87.1k | else /* unencrypted data should not be decrypted at all */ |
769 | 87.1k | numdecrypt = 0; |
770 | | |
771 | 87.1k | assert(numdecrypt >= 0); |
772 | | |
773 | | /* if there are bytes to decrypt, do that */ |
774 | 87.1k | if(numdecrypt > 0) { |
775 | | /* now decrypt the lot */ |
776 | 0 | if(CRYPT_FLAG_R(session, REQUIRES_FULL_PACKET)) { |
777 | 0 | rc = session->remote.crypt->crypt(session, |
778 | 0 | session->remote.seqno, |
779 | 0 | &p->buf[p->readidx], |
780 | 0 | numdecrypt, |
781 | 0 | &session->remote.crypt_abstract, |
782 | 0 | 0); |
783 | |
|
784 | 0 | if(rc != LIBSSH2_ERROR_NONE) { |
785 | 0 | p->total_num = 0; /* no packet buffer available */ |
786 | 0 | return rc; |
787 | 0 | } |
788 | | |
789 | 0 | memcpy(p->wptr, &p->buf[p->readidx], numbytes); |
790 | | |
791 | | /* advance read index past size field now that we have |
792 | | decrypted full packet */ |
793 | 0 | p->readidx += 4; |
794 | | |
795 | | /* include auth tag in bytes decrypted */ |
796 | 0 | numdecrypt += auth_len; |
797 | | |
798 | | /* set padding now that the packet has been verified and |
799 | | decrypted */ |
800 | 0 | p->padding_length = p->wptr[0]; |
801 | |
|
802 | 0 | if(p->padding_length > p->packet_length - 1) |
803 | 0 | return LIBSSH2_ERROR_DECRYPT; |
804 | 0 | } |
805 | 0 | else { |
806 | 0 | rc = transport_decrypt(session, &p->buf[p->readidx], p->wptr, |
807 | 0 | numdecrypt, firstlast); |
808 | |
|
809 | 0 | if(rc != LIBSSH2_ERROR_NONE) { |
810 | 0 | p->total_num = 0; /* no packet buffer available */ |
811 | 0 | return rc; |
812 | 0 | } |
813 | 0 | } |
814 | | |
815 | | /* advance the read pointer */ |
816 | 0 | p->readidx += numdecrypt; |
817 | | /* advance write pointer */ |
818 | 0 | p->wptr += numdecrypt; |
819 | | /* increase data_num */ |
820 | 0 | p->data_num += numdecrypt; |
821 | | |
822 | | /* bytes left to take care of without decryption */ |
823 | 0 | numbytes -= numdecrypt; |
824 | 0 | } |
825 | | |
826 | | /* if there are bytes to copy that are not decrypted, |
827 | | copy them as-is to the target buffer */ |
828 | 87.1k | if(numbytes > 0) { |
829 | | |
830 | 87.1k | if((size_t)numbytes <= (p->total_num - (p->wptr - p->payload))) |
831 | 87.1k | memcpy(p->wptr, &p->buf[p->readidx], numbytes); |
832 | 0 | else { |
833 | 0 | if(p->payload) |
834 | 0 | SSH2_SAFEFREE(session, p->payload); |
835 | 0 | return LIBSSH2_ERROR_OUT_OF_BOUNDARY; |
836 | 0 | } |
837 | | |
838 | | /* advance the read pointer */ |
839 | 87.1k | p->readidx += numbytes; |
840 | | /* advance write pointer */ |
841 | 87.1k | p->wptr += numbytes; |
842 | | /* increase data_num */ |
843 | 87.1k | p->data_num += numbytes; |
844 | 87.1k | } |
845 | | |
846 | | /* now check how much data there is left to read to finish the |
847 | | current packet */ |
848 | 87.1k | remainpack = p->total_num - p->data_num; |
849 | | |
850 | 87.1k | if(!remainpack) { |
851 | | /* we have a full packet */ |
852 | 86.7k | ssh2_transport_read_point1: |
853 | 86.7k | rc = transport_fullpacket(session, encrypted); |
854 | 86.7k | if(rc == LIBSSH2_ERROR_EAGAIN) { |
855 | |
|
856 | 0 | if(session->packAdd_state != ssh2_NB_state_idle) { |
857 | | /* transport_fullpacket() only returns LIBSSH2_ERROR_EAGAIN |
858 | | * if ssh2_packet_add() returns LIBSSH2_ERROR_EAGAIN. If |
859 | | * that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state |
860 | | * is idle, then the packet has been added to the brigade, |
861 | | * but some immediate action that was taken based on the |
862 | | * packet type (such as key re-exchange) is not yet |
863 | | * complete. Clear the way for a new packet to be read |
864 | | * in. |
865 | | */ |
866 | 0 | session->readPack_encrypted = encrypted; |
867 | 0 | session->readPack_state = ssh2_NB_state_jump1; |
868 | 0 | } |
869 | |
|
870 | 0 | return rc; |
871 | 0 | } |
872 | | |
873 | 86.7k | p->total_num = 0; /* no packet buffer available */ |
874 | | |
875 | 86.7k | return rc; |
876 | 86.7k | } |
877 | 87.1k | } while(1); /* loop */ |
878 | | |
879 | 0 | return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ |
880 | 89.0k | } |
881 | | |
882 | | static int transport_send_existing(LIBSSH2_SESSION *session, |
883 | | const unsigned char *data, |
884 | | size_t data_len, ssize_t *ret) |
885 | 21.1k | { |
886 | 21.1k | ssize_t rc; |
887 | 21.1k | ssize_t length; |
888 | 21.1k | struct transportpacket *p = &session->packet; |
889 | | |
890 | 21.1k | if(!p->olen) { |
891 | 21.1k | *ret = 0; |
892 | 21.1k | return LIBSSH2_ERROR_NONE; |
893 | 21.1k | } |
894 | | |
895 | | /* send as much as possible of the existing packet */ |
896 | 0 | if(data != p->odata || data_len != p->olen) { |
897 | | /* When we are about to complete the sending of a packet, it is vital |
898 | | that the caller does not try to send a new/different packet since |
899 | | we do not add this one up until the previous one has been sent. To |
900 | | make the caller really notice his/hers flaw, we return error for |
901 | | this case */ |
902 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
903 | 0 | "Address is different, returning EAGAIN")); |
904 | 0 | return LIBSSH2_ERROR_EAGAIN; |
905 | 0 | } |
906 | | |
907 | 0 | *ret = 1; /* set to make our parent return */ |
908 | | |
909 | | /* number of bytes left to send */ |
910 | 0 | length = p->ototal_num - p->osent; |
911 | |
|
912 | 0 | rc = SSH2_SEND(session, &p->outbuf[p->osent], length, |
913 | 0 | SSH2_SOCKET_SEND_FLAGS(session)); |
914 | 0 | if(rc < 0) |
915 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
916 | 0 | "Error sending %ld bytes: %ld", (long)length, (long)-rc)); |
917 | 0 | else { |
918 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
919 | 0 | "Sent %ld/%ld bytes at %p+%lu", (long)rc, (long)length, |
920 | 0 | (void *)p->outbuf, (unsigned long)p->osent)); |
921 | 0 | transport_debugdump(session, "ssh2_transport_send()", |
922 | 0 | &p->outbuf[p->osent], rc); |
923 | 0 | } |
924 | |
|
925 | 0 | if(rc == length) { |
926 | | /* the remainder of the package was sent */ |
927 | 0 | p->ototal_num = 0; |
928 | 0 | p->olen = 0; |
929 | | /* we leave *ret set so that the parent returns as we MUST return back |
930 | | a send success now, so that we do not risk sending EAGAIN later |
931 | | which then would confuse the parent function */ |
932 | 0 | return LIBSSH2_ERROR_NONE; |
933 | 0 | } |
934 | 0 | else if(rc < 0) { |
935 | | /* nothing was sent */ |
936 | 0 | if(rc != -EAGAIN) |
937 | | /* send failure! */ |
938 | 0 | return LIBSSH2_ERROR_SOCKET_SEND; |
939 | | |
940 | 0 | session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; |
941 | 0 | return LIBSSH2_ERROR_EAGAIN; |
942 | 0 | } |
943 | | |
944 | 0 | p->osent += rc; /* we sent away this much data */ |
945 | |
|
946 | 0 | return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE; |
947 | 0 | } |
948 | | |
949 | | /* |
950 | | * Send a packet, encrypting it and adding a MAC code if necessary |
951 | | * Returns 0 on success, non-zero on failure. |
952 | | * |
953 | | * The data is provided as _two_ data areas that are combined by this |
954 | | * function. The 'data' part is sent immediately before 'data2'. 'data2' may |
955 | | * be set to NULL to only use a single part. |
956 | | * |
957 | | * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was |
958 | | * not sent yet. If it does so, the caller should call this function again as |
959 | | * soon as it is likely that more data can be sent, and this function MUST |
960 | | * then be called with the same argument set (same data pointer and same |
961 | | * data_len) until ERROR_NONE or failure is returned. |
962 | | * |
963 | | * This function DOES NOT call ssh2_err() on any errors. |
964 | | */ |
965 | | int ssh2_transport_send(LIBSSH2_SESSION *session, |
966 | | const unsigned char *data, size_t data_len, |
967 | | const unsigned char *data2, size_t data2_len) |
968 | 21.1k | { |
969 | 21.1k | int blocksize = |
970 | 21.1k | (session->state & SSH2_STATE_NEWKEYS) ? |
971 | 21.1k | session->local.crypt->blocksize : 8; |
972 | 21.1k | ssize_t padding_length; |
973 | 21.1k | size_t packet_length; |
974 | 21.1k | ssize_t total_length; |
975 | | #ifdef LIBSSH2_RANDOM_PADDING |
976 | | int rand_max; |
977 | | int seed = data[0]; /* FIXME: make this random */ |
978 | | #endif |
979 | 21.1k | struct transportpacket *p = &session->packet; |
980 | 21.1k | int encrypted; |
981 | 21.1k | int compressed; |
982 | 21.1k | int etm; |
983 | 21.1k | ssize_t ret; |
984 | 21.1k | int rc; |
985 | 21.1k | const unsigned char *orgdata = data; |
986 | 21.1k | const struct mac_method *local_mac = NULL; |
987 | 21.1k | unsigned int auth_len = 0; |
988 | 21.1k | size_t orgdata_len = data_len; |
989 | 21.1k | size_t crypt_offset, etm_crypt_offset; |
990 | | |
991 | 21.1k | transport_debugdump(session, "ssh2_transport_send() plain", |
992 | 21.1k | data, data_len); |
993 | 21.1k | if(data2) |
994 | 65 | transport_debugdump(session, "ssh2_transport_send() plain2", |
995 | 65 | data2, data2_len); |
996 | | |
997 | | /* Finish flushing any partially-sent packet BEFORE redirecting into a key |
998 | | * re-exchange. A packet already in transmission can only be completed by |
999 | | * a transport_send call with that same packet (transport_send_existing() |
1000 | | * rejects a different data pointer with EAGAIN). If rekey runs first, |
1001 | | * a packet caught mid-send when rekey starts can never be flushed and |
1002 | | * the session deadlocks. RFC 4253 7.1 requires completing the in-flight |
1003 | | * packet; only NEW packets are withheld, which the rekey redirect (reached |
1004 | | * only once nothing is pending) still does. |
1005 | | * |
1006 | | * transport_send_existing() only sanity-checks data and data_len, not |
1007 | | * data2/data2_len. |
1008 | | */ |
1009 | 21.1k | rc = transport_send_existing(session, data, data_len, &ret); |
1010 | 21.1k | if(rc) |
1011 | 0 | return rc; |
1012 | | |
1013 | 21.1k | session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; |
1014 | | |
1015 | 21.1k | if(ret) |
1016 | | /* set by transport_send_existing() if data was sent */ |
1017 | 0 | return rc; |
1018 | | |
1019 | | /* |
1020 | | * If the last read operation was interrupted in the middle of a key |
1021 | | * exchange, we must complete that key exchange before writing further |
1022 | | * *new* data. See the similar block in ssh2_transport_read(). |
1023 | | */ |
1024 | 21.1k | if(session->state & SSH2_STATE_EXCHANGING_KEYS && |
1025 | 19.9k | !(session->state & SSH2_STATE_KEX_ACTIVE)) { |
1026 | | /* Do not write any new packets if we are still in the middle of a key |
1027 | | * exchange. */ |
1028 | 0 | ssh2_deb((session, LIBSSH2_TRACE_TRANS, "Redirecting into the" |
1029 | 0 | " key re-exchange from ssh2_transport_send()")); |
1030 | 0 | rc = ssh2_kex_exchange(session, 1, &session->startup_key_state); |
1031 | 0 | if(rc) |
1032 | 0 | return rc; |
1033 | 0 | } |
1034 | | |
1035 | 21.1k | encrypted = (session->state & SSH2_STATE_NEWKEYS) ? 1 : 0; |
1036 | | |
1037 | 21.1k | if(encrypted && session->local.crypt && |
1038 | 0 | CRYPT_FLAG_L(session, REQUIRES_FULL_PACKET)) |
1039 | 0 | auth_len = session->local.crypt->auth_len; |
1040 | 21.1k | else |
1041 | 21.1k | local_mac = session->local.mac; |
1042 | | |
1043 | 21.1k | etm = encrypted && local_mac ? local_mac->etm : 0; |
1044 | | |
1045 | 21.1k | compressed = session->local.comp && |
1046 | 14.1k | session->local.comp->compress && |
1047 | 0 | ((session->state & SSH2_STATE_AUTHENTICATED) || |
1048 | 0 | session->local.comp->use_in_auth); |
1049 | | |
1050 | 21.1k | if(encrypted && compressed && session->local.comp_abstract) { |
1051 | | /* the idea here is that these function must fail if the output gets |
1052 | | larger than what fits in the assigned buffer so thus they do not |
1053 | | check the input size as we do not know how much it compresses */ |
1054 | 0 | size_t dest_len = MAX_SSH_PACKET_LEN - 5 - 256; |
1055 | 0 | size_t dest2_len = dest_len; |
1056 | | |
1057 | | /* compress directly to the target buffer */ |
1058 | 0 | rc = session->local.comp->comp(session, |
1059 | 0 | &p->outbuf[5], &dest_len, |
1060 | 0 | data, data_len, |
1061 | 0 | &session->local.comp_abstract); |
1062 | 0 | if(rc) |
1063 | 0 | return rc; /* compression failure */ |
1064 | | |
1065 | 0 | if(data2 && data2_len) { |
1066 | | /* compress directly to the target buffer right after where the |
1067 | | previous call put data */ |
1068 | 0 | dest2_len -= dest_len; |
1069 | |
|
1070 | 0 | rc = session->local.comp->comp(session, |
1071 | 0 | &p->outbuf[5 + dest_len], |
1072 | 0 | &dest2_len, |
1073 | 0 | data2, data2_len, |
1074 | 0 | &session->local.comp_abstract); |
1075 | 0 | } |
1076 | 0 | else |
1077 | 0 | dest2_len = 0; |
1078 | 0 | if(rc) |
1079 | 0 | return rc; /* compression failure */ |
1080 | | |
1081 | 0 | data_len = dest_len + dest2_len; /* use the combined length */ |
1082 | 0 | } |
1083 | 21.1k | else { |
1084 | 21.1k | if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN - 0x100)) |
1085 | | /* too large packet, return error for this until we make this |
1086 | | function split it up and send multiple SSH packets */ |
1087 | 0 | return LIBSSH2_ERROR_INVAL; |
1088 | | |
1089 | | /* copy the payload data */ |
1090 | 21.1k | memcpy(&p->outbuf[5], data, data_len); |
1091 | 21.1k | if(data2 && data2_len) |
1092 | 0 | memcpy(&p->outbuf[5 + data_len], data2, data2_len); |
1093 | 21.1k | data_len += data2_len; /* use the combined length */ |
1094 | 21.1k | } |
1095 | | |
1096 | | /* RFC4253 says: Note that the length of the concatenation of |
1097 | | 'packet_length', 'padding_length', 'payload', and 'random padding' |
1098 | | MUST be a multiple of the cipher block size or 8, whichever is |
1099 | | larger. */ |
1100 | | |
1101 | | /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ |
1102 | | |
1103 | 21.1k | packet_length = data_len + 1 + 4; /* 1 is for padding_length field |
1104 | | 4 for the packet_length field */ |
1105 | | /* subtract 4 bytes of the packet_length field when padding AES-GCM |
1106 | | or with ETM */ |
1107 | 21.1k | crypt_offset = (etm || auth_len || |
1108 | 21.1k | (encrypted && CRYPT_FLAG_L(session, PKTLEN_AAD))) |
1109 | 21.1k | ? 4 : 0; |
1110 | 21.1k | etm_crypt_offset = etm ? 4 : 0; |
1111 | | |
1112 | | /* at this point we have it all except the padding */ |
1113 | | |
1114 | | /* first figure out our minimum padding amount to make it an even |
1115 | | block size */ |
1116 | 21.1k | padding_length = blocksize - ((packet_length - crypt_offset) % blocksize); |
1117 | | |
1118 | | /* if the padding becomes too small we add another blocksize worth |
1119 | | of it (taken from the original libssh2 where it did not have any |
1120 | | real explanation) */ |
1121 | 21.1k | if(padding_length < 4) |
1122 | 3.87k | padding_length += blocksize; |
1123 | | #ifdef LIBSSH2_RANDOM_PADDING |
1124 | | /* FIXME: we can add padding here, but that also makes the packets |
1125 | | bigger etc */ |
1126 | | |
1127 | | /* now we can add 'blocksize' to the padding_length N number of times |
1128 | | (to "help thwart traffic analysis") but it must be less than 255 in |
1129 | | total */ |
1130 | | rand_max = (255 - padding_length) / blocksize + 1; |
1131 | | padding_length += blocksize * (seed % rand_max); |
1132 | | #endif |
1133 | | |
1134 | 21.1k | packet_length += padding_length; |
1135 | | |
1136 | | /* append the MAC length to the total_length size */ |
1137 | 21.1k | total_length = |
1138 | 21.1k | packet_length + (encrypted && local_mac ? local_mac->mac_len : 0); |
1139 | | |
1140 | 21.1k | total_length += auth_len; |
1141 | | |
1142 | | /* store packet_length, which is the size of the whole packet except |
1143 | | the MAC and the packet_length field itself */ |
1144 | 21.1k | ssh2_htonu32(p->outbuf, (uint32_t)(packet_length - 4)); |
1145 | | /* store padding_length */ |
1146 | 21.1k | p->outbuf[4] = (unsigned char)padding_length; |
1147 | | |
1148 | | /* fill the padding area with random junk */ |
1149 | 21.1k | if(ssh2_random(p->outbuf + 5 + data_len, padding_length)) |
1150 | 0 | return ssh2_err(session, LIBSSH2_ERROR_RANDGEN, |
1151 | 0 | "Unable to get random bytes for packet padding"); |
1152 | | |
1153 | 21.1k | if(encrypted) { |
1154 | 0 | size_t i; |
1155 | | |
1156 | | /* Calculate MAC hash. Put the output at index packet_length, |
1157 | | since that size includes the whole packet. The MAC is |
1158 | | calculated on the entire unencrypted packet, including all |
1159 | | fields except the MAC field itself. This is skipped in the |
1160 | | INTEGRATED_MAC case, where the crypto algorithm also does its |
1161 | | own hash. */ |
1162 | 0 | if(!etm && local_mac && !CRYPT_FLAG_L(session, INTEGRATED_MAC)) { |
1163 | 0 | if(local_mac->hash(session, p->outbuf + packet_length, |
1164 | 0 | session->local.seqno, p->outbuf, |
1165 | 0 | packet_length, NULL, 0, |
1166 | 0 | &session->local.mac_abstract)) |
1167 | 0 | return ssh2_err(session, LIBSSH2_ERROR_MAC_FAILURE, |
1168 | 0 | "Failed to calculate MAC"); |
1169 | 0 | } |
1170 | | |
1171 | 0 | if(CRYPT_FLAG_L(session, REQUIRES_FULL_PACKET)) { |
1172 | 0 | if(session->local.crypt->crypt(session, |
1173 | 0 | session->local.seqno, |
1174 | 0 | p->outbuf, |
1175 | 0 | packet_length, |
1176 | 0 | &session->local.crypt_abstract, |
1177 | 0 | 0)) |
1178 | 0 | return LIBSSH2_ERROR_ENCRYPT; |
1179 | 0 | } |
1180 | 0 | else { |
1181 | | /* Encrypt the whole packet data, one block size at a time. |
1182 | | The MAC field is not encrypted unless INTEGRATED_MAC. */ |
1183 | | /* Some crypto back-ends could handle a single crypt() call for |
1184 | | encryption, but (presumably) others cannot, so break it up |
1185 | | into blocksize-sized chunks to satisfy them all. */ |
1186 | 0 | for(i = etm_crypt_offset; i < packet_length; |
1187 | 0 | i += session->local.crypt->blocksize) { |
1188 | 0 | unsigned char *ptr = &p->outbuf[i]; |
1189 | 0 | size_t bsize = SSH2_MIN(session->local.crypt->blocksize, |
1190 | 0 | (int)(packet_length - i)); |
1191 | | /* The INTEGRATED_MAC case always has an extra call below, so |
1192 | | it never is LAST_BLOCK up here. */ |
1193 | 0 | int firstlast = i == 0 ? FIRST_BLOCK : |
1194 | 0 | (!CRYPT_FLAG_L(session, INTEGRATED_MAC) && |
1195 | 0 | (i == packet_length - session->local.crypt->blocksize) |
1196 | 0 | ? LAST_BLOCK : MIDDLE_BLOCK); |
1197 | | /* In the AAD case, the last block would be only 4 bytes |
1198 | | because everything is offset by 4 since the initial |
1199 | | packet_length is not encrypted. In this case, combine that |
1200 | | last short packet with the previous one since AES-GCM |
1201 | | crypt() assumes that the entire MAC is available in that |
1202 | | packet so it can set that to the authentication tag. */ |
1203 | 0 | if(!CRYPT_FLAG_L(session, INTEGRATED_MAC) && |
1204 | 0 | i > packet_length - 2 * bsize) { |
1205 | | /* increase the final block size */ |
1206 | 0 | bsize = packet_length - i; |
1207 | | /* advance the loop counter by the extra amount */ |
1208 | 0 | i += bsize - session->local.crypt->blocksize; |
1209 | 0 | } |
1210 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
1211 | 0 | "crypting bytes %lu-%lu", (unsigned long)i, |
1212 | 0 | (unsigned long)(i + bsize - 1))); |
1213 | 0 | if(session->local.crypt->crypt(session, 0, ptr, bsize, |
1214 | 0 | &session->local.crypt_abstract, |
1215 | 0 | firstlast)) |
1216 | 0 | return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ |
1217 | 0 | } |
1218 | | |
1219 | | /* Call crypt() one last time so it can be filled in with the |
1220 | | MAC */ |
1221 | 0 | if(CRYPT_FLAG_L(session, INTEGRATED_MAC)) { |
1222 | 0 | int authlen = local_mac ? local_mac->mac_len : 0; |
1223 | 0 | assert((size_t)total_length <= |
1224 | 0 | packet_length + session->local.crypt->blocksize); |
1225 | 0 | if(session->local.crypt->crypt(session, 0, |
1226 | 0 | &p->outbuf[packet_length], |
1227 | 0 | authlen, |
1228 | 0 | &session->local.crypt_abstract, |
1229 | 0 | LAST_BLOCK)) |
1230 | 0 | return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ |
1231 | 0 | } |
1232 | 0 | } |
1233 | | |
1234 | 0 | if(etm) { |
1235 | | /* Calculate MAC hash. Put the output at index packet_length, |
1236 | | since that size includes the whole packet. The MAC is |
1237 | | calculated on the entire packet (length plain the rest |
1238 | | encrypted), including all fields except the MAC field |
1239 | | itself. */ |
1240 | 0 | if(local_mac->hash(session, p->outbuf + packet_length, |
1241 | 0 | session->local.seqno, p->outbuf, |
1242 | 0 | packet_length, NULL, 0, |
1243 | 0 | &session->local.mac_abstract)) |
1244 | 0 | return ssh2_err(session, LIBSSH2_ERROR_MAC_FAILURE, |
1245 | 0 | "Failed to calculate MAC"); |
1246 | 0 | } |
1247 | 0 | } |
1248 | | |
1249 | 21.1k | session->local.seqno++; |
1250 | | |
1251 | 21.1k | if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) |
1252 | 0 | session->local.seqno = 0; |
1253 | | |
1254 | 21.1k | ret = SSH2_SEND(session, p->outbuf, total_length, |
1255 | 21.1k | SSH2_SOCKET_SEND_FLAGS(session)); |
1256 | 21.1k | if(ret < 0) |
1257 | 0 | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
1258 | 21.1k | "Error sending %ld bytes: %ld", |
1259 | 21.1k | (long)total_length, (long)-ret)); |
1260 | 21.1k | else { |
1261 | 21.1k | ssh2_deb((session, LIBSSH2_TRACE_SOCKET, |
1262 | 21.1k | "Sent %ld/%ld bytes at %p", |
1263 | 21.1k | (long)ret, (long)total_length, (void *)p->outbuf)); |
1264 | 21.1k | transport_debugdump(session, "ssh2_transport_send()", p->outbuf, ret); |
1265 | 21.1k | } |
1266 | | |
1267 | 21.1k | if(ret != total_length) { |
1268 | 0 | if(ret >= 0 || ret == -EAGAIN) { |
1269 | | /* the whole packet could not be sent, save the rest */ |
1270 | 0 | session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; |
1271 | 0 | p->odata = orgdata; |
1272 | 0 | p->olen = orgdata_len; |
1273 | 0 | p->osent = ret <= 0 ? 0 : ret; |
1274 | 0 | p->ototal_num = total_length; |
1275 | 0 | return LIBSSH2_ERROR_EAGAIN; |
1276 | 0 | } |
1277 | 0 | return LIBSSH2_ERROR_SOCKET_SEND; |
1278 | 0 | } |
1279 | | |
1280 | | /* the whole thing got sent away */ |
1281 | 21.1k | p->odata = NULL; |
1282 | 21.1k | p->olen = 0; |
1283 | | |
1284 | 21.1k | return LIBSSH2_ERROR_NONE; /* all is good */ |
1285 | 21.1k | } |