remove unused variable
[dropbear.git] / packet.c
blobea96c0497205f5a7ea204e6ede6b3c93c4907c1a
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
25 #include "includes.h"
26 #include "packet.h"
27 #include "session.h"
28 #include "dbutil.h"
29 #include "ssh.h"
30 #include "algo.h"
31 #include "buffer.h"
32 #include "kex.h"
33 #include "random.h"
34 #include "service.h"
35 #include "auth.h"
36 #include "channel.h"
38 static int read_packet_init();
39 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
40 buffer * clear_buf, unsigned int clear_len,
41 unsigned char *output_mac);
42 static int checkmac();
44 #define ZLIB_COMPRESS_INCR 20 /* this is 12 bytes + 0.1% of 8000 bytes */
45 #define ZLIB_DECOMPRESS_INCR 100
46 #ifndef DISABLE_ZLIB
47 static buffer* buf_decompress(buffer* buf, unsigned int len);
48 static void buf_compress(buffer * dest, buffer * src, unsigned int len);
49 #endif
51 /* non-blocking function writing out a current encrypted packet */
52 void write_packet() {
54 int len, written;
55 buffer * writebuf = NULL;
57 TRACE(("enter write_packet"))
58 dropbear_assert(!isempty(&ses.writequeue));
60 /* Get the next buffer in the queue of encrypted packets to write*/
61 writebuf = (buffer*)examine(&ses.writequeue);
63 len = writebuf->len - writebuf->pos;
64 dropbear_assert(len > 0);
65 /* Try to write as much as possible */
66 written = write(ses.sock_out, buf_getptr(writebuf, len), len);
68 if (written < 0) {
69 if (errno == EINTR) {
70 TRACE(("leave writepacket: EINTR"))
71 return;
72 } else {
73 dropbear_exit("error writing");
77 ses.last_trx_packet_time = time(NULL);
78 ses.last_packet_time = time(NULL);
80 if (written == 0) {
81 ses.remoteclosed();
84 if (written == len) {
85 /* We've finished with the packet, free it */
86 dequeue(&ses.writequeue);
87 buf_free(writebuf);
88 writebuf = NULL;
89 } else {
90 /* More packet left to write, leave it in the queue for later */
91 buf_incrpos(writebuf, written);
94 TRACE(("leave write_packet"))
97 /* Non-blocking function reading available portion of a packet into the
98 * ses's buffer, decrypting the length if encrypted, decrypting the
99 * full portion if possible */
100 void read_packet() {
102 int len;
103 unsigned int maxlen;
104 unsigned char blocksize;
106 TRACE(("enter read_packet"))
107 blocksize = ses.keys->recv.algo_crypt->blocksize;
109 if (ses.readbuf == NULL || ses.readbuf->len < blocksize) {
110 int ret;
111 /* In the first blocksize of a packet */
113 /* Read the first blocksize of the packet, so we can decrypt it and
114 * find the length of the whole packet */
115 ret = read_packet_init();
117 if (ret == DROPBEAR_FAILURE) {
118 /* didn't read enough to determine the length */
119 TRACE(("leave read_packet: packetinit done"))
120 return;
124 /* Attempt to read the remainder of the packet, note that there
125 * mightn't be any available (EAGAIN) */
126 maxlen = ses.readbuf->len - ses.readbuf->pos;
127 len = read(ses.sock_in, buf_getptr(ses.readbuf, maxlen), maxlen);
129 if (len == 0) {
130 ses.remoteclosed();
133 if (len < 0) {
134 if (errno == EINTR || errno == EAGAIN) {
135 TRACE(("leave read_packet: EINTR or EAGAIN"))
136 return;
137 } else {
138 dropbear_exit("error reading: %s", strerror(errno));
142 buf_incrpos(ses.readbuf, len);
144 if ((unsigned int)len == maxlen) {
145 /* The whole packet has been read */
146 decrypt_packet();
147 /* The main select() loop process_packet() to
148 * handle the packet contents... */
150 TRACE(("leave read_packet"))
153 /* Function used to read the initial portion of a packet, and determine the
154 * length. Only called during the first BLOCKSIZE of a packet. */
155 /* Returns DROPBEAR_SUCCESS if the length is determined,
156 * DROPBEAR_FAILURE otherwise */
157 static int read_packet_init() {
159 unsigned int maxlen;
160 int slen;
161 unsigned int len;
162 unsigned int blocksize;
163 unsigned int macsize;
166 blocksize = ses.keys->recv.algo_crypt->blocksize;
167 macsize = ses.keys->recv.algo_mac->hashsize;
169 if (ses.readbuf == NULL) {
170 /* start of a new packet */
171 ses.readbuf = buf_new(INIT_READBUF);
174 maxlen = blocksize - ses.readbuf->pos;
176 /* read the rest of the packet if possible */
177 slen = read(ses.sock_in, buf_getwriteptr(ses.readbuf, maxlen),
178 maxlen);
179 if (slen == 0) {
180 ses.remoteclosed();
182 if (slen < 0) {
183 if (errno == EINTR) {
184 TRACE(("leave read_packet_init: EINTR"))
185 return DROPBEAR_FAILURE;
187 dropbear_exit("error reading: %s", strerror(errno));
190 buf_incrwritepos(ses.readbuf, slen);
192 if ((unsigned int)slen != maxlen) {
193 /* don't have enough bytes to determine length, get next time */
194 return DROPBEAR_FAILURE;
197 /* now we have the first block, need to get packet length, so we decrypt
198 * the first block (only need first 4 bytes) */
199 buf_setpos(ses.readbuf, 0);
200 if (ses.keys->recv.crypt_mode->decrypt(buf_getptr(ses.readbuf, blocksize),
201 buf_getwriteptr(ses.readbuf, blocksize),
202 blocksize,
203 &ses.keys->recv.cipher_state) != CRYPT_OK) {
204 dropbear_exit("error decrypting");
206 len = buf_getint(ses.readbuf) + 4 + macsize;
208 TRACE(("packet size is %d, block %d mac %d", len, blocksize, macsize))
211 /* check packet length */
212 if ((len > RECV_MAX_PACKET_LEN) ||
213 (len < MIN_PACKET_LEN + macsize) ||
214 ((len - macsize) % blocksize != 0)) {
215 dropbear_exit("bad packet size %d", len);
218 if (len > ses.readbuf->size) {
219 buf_resize(ses.readbuf, len);
221 buf_setlen(ses.readbuf, len);
222 buf_setpos(ses.readbuf, blocksize);
223 return DROPBEAR_SUCCESS;
226 /* handle the received packet */
227 void decrypt_packet() {
229 unsigned char blocksize;
230 unsigned char macsize;
231 unsigned int padlen;
232 unsigned int len;
234 TRACE(("enter decrypt_packet"))
235 blocksize = ses.keys->recv.algo_crypt->blocksize;
236 macsize = ses.keys->recv.algo_mac->hashsize;
238 ses.kexstate.datarecv += ses.readbuf->len;
240 /* we've already decrypted the first blocksize in read_packet_init */
241 buf_setpos(ses.readbuf, blocksize);
243 /* decrypt it in-place */
244 len = ses.readbuf->len - macsize - ses.readbuf->pos;
245 if (ses.keys->recv.crypt_mode->decrypt(
246 buf_getptr(ses.readbuf, len),
247 buf_getwriteptr(ses.readbuf, len),
248 len,
249 &ses.keys->recv.cipher_state) != CRYPT_OK) {
250 dropbear_exit("error decrypting");
252 buf_incrpos(ses.readbuf, len);
254 /* check the hmac */
255 if (checkmac() != DROPBEAR_SUCCESS) {
256 dropbear_exit("Integrity error");
259 /* get padding length */
260 buf_setpos(ses.readbuf, PACKET_PADDING_OFF);
261 padlen = buf_getbyte(ses.readbuf);
263 /* payload length */
264 /* - 4 - 1 is for LEN and PADLEN values */
265 len = ses.readbuf->len - padlen - 4 - 1 - macsize;
266 if ((len > RECV_MAX_PAYLOAD_LEN) || (len < 1)) {
267 dropbear_exit("bad packet size");
270 buf_setpos(ses.readbuf, PACKET_PAYLOAD_OFF);
272 #ifndef DISABLE_ZLIB
273 if (is_compress_recv()) {
274 /* decompress */
275 ses.payload = buf_decompress(ses.readbuf, len);
276 } else
277 #endif
279 /* copy payload */
280 ses.payload = buf_new(len);
281 memcpy(ses.payload->data, buf_getptr(ses.readbuf, len), len);
282 buf_incrlen(ses.payload, len);
285 buf_free(ses.readbuf);
286 ses.readbuf = NULL;
287 buf_setpos(ses.payload, 0);
289 ses.recvseq++;
291 TRACE(("leave decrypt_packet"))
294 /* Checks the mac at the end of a decrypted readbuf.
295 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
296 static int checkmac() {
298 unsigned char mac_bytes[MAX_MAC_LEN];
299 unsigned int mac_size, contents_len;
301 mac_size = ses.keys->trans.algo_mac->hashsize;
302 contents_len = ses.readbuf->len - mac_size;
304 buf_setpos(ses.readbuf, 0);
305 make_mac(ses.recvseq, &ses.keys->recv, ses.readbuf, contents_len, mac_bytes);
307 /* compare the hash */
308 buf_setpos(ses.readbuf, contents_len);
309 if (memcmp(mac_bytes, buf_getptr(ses.readbuf, mac_size), mac_size) != 0) {
310 return DROPBEAR_FAILURE;
311 } else {
312 return DROPBEAR_SUCCESS;
316 #ifndef DISABLE_ZLIB
317 /* returns a pointer to a newly created buffer */
318 static buffer* buf_decompress(buffer* buf, unsigned int len) {
320 int result;
321 buffer * ret;
322 z_streamp zstream;
324 zstream = ses.keys->recv.zstream;
325 ret = buf_new(len);
327 zstream->avail_in = len;
328 zstream->next_in = buf_getptr(buf, len);
330 /* decompress the payload, incrementally resizing the output buffer */
331 while (1) {
333 zstream->avail_out = ret->size - ret->pos;
334 zstream->next_out = buf_getwriteptr(ret, zstream->avail_out);
336 result = inflate(zstream, Z_SYNC_FLUSH);
338 buf_setlen(ret, ret->size - zstream->avail_out);
339 buf_setpos(ret, ret->len);
341 if (result != Z_BUF_ERROR && result != Z_OK) {
342 dropbear_exit("zlib error");
345 if (zstream->avail_in == 0 &&
346 (zstream->avail_out != 0 || result == Z_BUF_ERROR)) {
347 /* we can only exit if avail_out hasn't all been used,
348 * and there's no remaining input */
349 return ret;
352 if (zstream->avail_out == 0) {
353 buf_resize(ret, ret->size + ZLIB_DECOMPRESS_INCR);
357 #endif
360 /* returns 1 if the packet is a valid type during kex (see 7.1 of rfc4253) */
361 static int packet_is_okay_kex(unsigned char type) {
362 if (type >= SSH_MSG_USERAUTH_REQUEST) {
363 return 0;
365 if (type == SSH_MSG_SERVICE_REQUEST || type == SSH_MSG_SERVICE_ACCEPT) {
366 return 0;
368 if (type == SSH_MSG_KEXINIT) {
369 /* XXX should this die horribly if !dataallowed ?? */
370 return 0;
372 return 1;
375 static void enqueue_reply_packet() {
376 struct packetlist * new_item = NULL;
377 new_item = m_malloc(sizeof(struct packetlist));
378 new_item->next = NULL;
380 new_item->payload = buf_newcopy(ses.writepayload);
381 buf_setpos(ses.writepayload, 0);
382 buf_setlen(ses.writepayload, 0);
384 if (ses.reply_queue_tail) {
385 ses.reply_queue_tail->next = new_item;
386 } else {
387 ses.reply_queue_head = new_item;
389 ses.reply_queue_tail = new_item;
390 TRACE(("leave enqueue_reply_packet"))
393 void maybe_flush_reply_queue() {
394 struct packetlist *tmp_item = NULL, *curr_item = NULL;
395 if (!ses.dataallowed)
397 TRACE(("maybe_empty_reply_queue - no data allowed"))
398 return;
401 for (curr_item = ses.reply_queue_head; curr_item; ) {
402 CHECKCLEARTOWRITE();
403 buf_putbytes(ses.writepayload,
404 curr_item->payload->data, curr_item->payload->len);
406 buf_free(curr_item->payload);
407 tmp_item = curr_item;
408 curr_item = curr_item->next;
409 m_free(tmp_item);
410 encrypt_packet();
412 ses.reply_queue_head = ses.reply_queue_tail = NULL;
415 /* encrypt the writepayload, putting into writebuf, ready for write_packet()
416 * to put on the wire */
417 void encrypt_packet() {
419 unsigned char padlen;
420 unsigned char blocksize, mac_size;
421 buffer * writebuf; /* the packet which will go on the wire. This is
422 encrypted in-place. */
423 unsigned char type;
424 unsigned int len, encrypt_buf_size;
425 unsigned char mac_bytes[MAX_MAC_LEN];
427 type = ses.writepayload->data[0];
428 TRACE(("enter encrypt_packet()"))
429 TRACE(("encrypt_packet type is %d", type))
431 if (!ses.dataallowed && !packet_is_okay_kex(type)) {
432 /* During key exchange only particular packets are allowed.
433 Since this type isn't OK we just enqueue it to send
434 after the KEX, see maybe_flush_reply_queue */
435 enqueue_reply_packet();
436 return;
439 blocksize = ses.keys->trans.algo_crypt->blocksize;
440 mac_size = ses.keys->trans.algo_mac->hashsize;
442 /* Encrypted packet len is payload+5, then worst case is if we are 3 away
443 * from a blocksize multiple. In which case we need to pad to the
444 * multiple, then add another blocksize (or MIN_PACKET_LEN) */
445 encrypt_buf_size = (ses.writepayload->len+4+1) + MIN_PACKET_LEN + 3;
446 /* add space for the MAC at the end */
447 encrypt_buf_size += mac_size;
449 #ifndef DISABLE_ZLIB
450 encrypt_buf_size += ZLIB_COMPRESS_INCR; /* bit of a kludge, but we can't know len*/
451 #endif
452 writebuf = buf_new(encrypt_buf_size);
453 buf_setlen(writebuf, PACKET_PAYLOAD_OFF);
454 buf_setpos(writebuf, PACKET_PAYLOAD_OFF);
456 buf_setpos(ses.writepayload, 0);
458 #ifndef DISABLE_ZLIB
459 /* compression */
460 if (is_compress_trans()) {
461 buf_compress(writebuf, ses.writepayload, ses.writepayload->len);
462 } else
463 #endif
465 memcpy(buf_getwriteptr(writebuf, ses.writepayload->len),
466 buf_getptr(ses.writepayload, ses.writepayload->len),
467 ses.writepayload->len);
468 buf_incrwritepos(writebuf, ses.writepayload->len);
471 /* finished with payload */
472 buf_setpos(ses.writepayload, 0);
473 buf_setlen(ses.writepayload, 0);
475 /* length of padding - packet length must be a multiple of blocksize,
476 * with a minimum of 4 bytes of padding */
477 padlen = blocksize - (writebuf->len) % blocksize;
478 if (padlen < 4) {
479 padlen += blocksize;
481 /* check for min packet length */
482 if (writebuf->len + padlen < MIN_PACKET_LEN) {
483 padlen += blocksize;
486 buf_setpos(writebuf, 0);
487 /* packet length excluding the packetlength uint32 */
488 buf_putint(writebuf, writebuf->len + padlen - 4);
490 /* padding len */
491 buf_putbyte(writebuf, padlen);
492 /* actual padding */
493 buf_setpos(writebuf, writebuf->len);
494 buf_incrlen(writebuf, padlen);
495 genrandom(buf_getptr(writebuf, padlen), padlen);
497 make_mac(ses.transseq, &ses.keys->trans, writebuf, writebuf->len, mac_bytes);
499 /* do the actual encryption, in-place */
500 buf_setpos(writebuf, 0);
501 /* encrypt it in-place*/
502 len = writebuf->len;
503 if (ses.keys->trans.crypt_mode->encrypt(
504 buf_getptr(writebuf, len),
505 buf_getwriteptr(writebuf, len),
506 len,
507 &ses.keys->trans.cipher_state) != CRYPT_OK) {
508 dropbear_exit("error encrypting");
510 buf_incrpos(writebuf, len);
512 /* stick the MAC on it */
513 buf_putbytes(writebuf, mac_bytes, mac_size);
515 /* enqueue the packet for sending. It will get freed after transmission. */
516 buf_setpos(writebuf, 0);
517 enqueue(&ses.writequeue, (void*)writebuf);
519 /* Update counts */
520 ses.kexstate.datatrans += writebuf->len;
521 ses.transseq++;
523 TRACE(("leave encrypt_packet()"))
527 /* Create the packet mac, and append H(seqno|clearbuf) to the output */
528 /* output_mac must have ses.keys->trans.algo_mac->hashsize bytes. */
529 static void make_mac(unsigned int seqno, const struct key_context_directional * key_state,
530 buffer * clear_buf, unsigned int clear_len,
531 unsigned char *output_mac) {
532 unsigned char seqbuf[4];
533 unsigned long bufsize;
534 hmac_state hmac;
536 TRACE(("enter writemac"))
538 if (key_state->algo_mac->hashsize > 0) {
539 /* calculate the mac */
540 if (hmac_init(&hmac,
541 key_state->hash_index,
542 key_state->mackey,
543 key_state->algo_mac->keysize) != CRYPT_OK) {
544 dropbear_exit("HMAC error");
547 /* sequence number */
548 STORE32H(seqno, seqbuf);
549 if (hmac_process(&hmac, seqbuf, 4) != CRYPT_OK) {
550 dropbear_exit("HMAC error");
553 /* the actual contents */
554 buf_setpos(clear_buf, 0);
555 if (hmac_process(&hmac,
556 buf_getptr(clear_buf, clear_len),
557 clear_len) != CRYPT_OK) {
558 dropbear_exit("HMAC error");
561 bufsize = MAX_MAC_LEN;
562 if (hmac_done(&hmac, output_mac, &bufsize) != CRYPT_OK) {
563 dropbear_exit("HMAC error");
566 TRACE(("leave writemac"))
569 #ifndef DISABLE_ZLIB
570 /* compresses len bytes from src, outputting to dest (starting from the
571 * respective current positions. */
572 static void buf_compress(buffer * dest, buffer * src, unsigned int len) {
574 unsigned int endpos = src->pos + len;
575 int result;
577 TRACE(("enter buf_compress"))
579 while (1) {
581 ses.keys->trans.zstream->avail_in = endpos - src->pos;
582 ses.keys->trans.zstream->next_in =
583 buf_getptr(src, ses.keys->trans.zstream->avail_in);
585 ses.keys->trans.zstream->avail_out = dest->size - dest->pos;
586 ses.keys->trans.zstream->next_out =
587 buf_getwriteptr(dest, ses.keys->trans.zstream->avail_out);
589 result = deflate(ses.keys->trans.zstream, Z_SYNC_FLUSH);
591 buf_setpos(src, endpos - ses.keys->trans.zstream->avail_in);
592 buf_setlen(dest, dest->size - ses.keys->trans.zstream->avail_out);
593 buf_setpos(dest, dest->len);
595 if (result != Z_OK) {
596 dropbear_exit("zlib error");
599 if (ses.keys->trans.zstream->avail_in == 0) {
600 break;
603 dropbear_assert(ses.keys->trans.zstream->avail_out == 0);
605 /* the buffer has been filled, we must extend. This only happens in
606 * unusual circumstances where the data grows in size after deflate(),
607 * but it is possible */
608 buf_resize(dest, dest->size + ZLIB_COMPRESS_INCR);
611 TRACE(("leave buf_compress"))
613 #endif