comparison common-channel.c @ 165:0cfba3034be5

Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
author Matt Johnston <matt@ucc.asn.au>
date Sun, 02 Jan 2005 20:25:56 +0000
parents 8c2b3506f112
children 161557a9dde8
comparison
equal deleted inserted replaced
161:b9d3f725e00b 165:0cfba3034be5
79 /* Clean up channels, freeing allocated memory */ 79 /* Clean up channels, freeing allocated memory */
80 void chancleanup() { 80 void chancleanup() {
81 81
82 unsigned int i; 82 unsigned int i;
83 83
84 TRACE(("enter chancleanup")); 84 TRACE(("enter chancleanup"))
85 for (i = 0; i < ses.chansize; i++) { 85 for (i = 0; i < ses.chansize; i++) {
86 if (ses.channels[i] != NULL) { 86 if (ses.channels[i] != NULL) {
87 TRACE(("channel %d closing", i)); 87 TRACE(("channel %d closing", i))
88 removechannel(ses.channels[i]); 88 removechannel(ses.channels[i]);
89 } 89 }
90 } 90 }
91 m_free(ses.channels); 91 m_free(ses.channels);
92 TRACE(("leave chancleanup")); 92 TRACE(("leave chancleanup"))
93 } 93 }
94 94
95 /* Create a new channel entry, send a reply confirm or failure */ 95 /* Create a new channel entry, send a reply confirm or failure */
96 /* If remotechan, transwindow and transmaxpacket are not know (for a new 96 /* If remotechan, transwindow and transmaxpacket are not know (for a new
97 * outgoing connection, with them to be filled on confirmation), they should 97 * outgoing connection, with them to be filled on confirmation), they should
101 unsigned int transwindow, unsigned int transmaxpacket) { 101 unsigned int transwindow, unsigned int transmaxpacket) {
102 102
103 struct Channel * newchan; 103 struct Channel * newchan;
104 unsigned int i, j; 104 unsigned int i, j;
105 105
106 TRACE(("enter newchannel")); 106 TRACE(("enter newchannel"))
107 107
108 /* first see if we can use existing channels */ 108 /* first see if we can use existing channels */
109 for (i = 0; i < ses.chansize; i++) { 109 for (i = 0; i < ses.chansize; i++) {
110 if (ses.channels[i] == NULL) { 110 if (ses.channels[i] == NULL) {
111 break; 111 break;
113 } 113 }
114 114
115 /* otherwise extend the list */ 115 /* otherwise extend the list */
116 if (i == ses.chansize) { 116 if (i == ses.chansize) {
117 if (ses.chansize >= MAX_CHANNELS) { 117 if (ses.chansize >= MAX_CHANNELS) {
118 TRACE(("leave newchannel: max chans reached")); 118 TRACE(("leave newchannel: max chans reached"))
119 return NULL; 119 return NULL;
120 } 120 }
121 121
122 /* extend the channels */ 122 /* extend the channels */
123 ses.channels = (struct Channel**)m_realloc(ses.channels, 123 ses.channels = (struct Channel**)m_realloc(ses.channels,
155 newchan->recvmaxpacket = RECV_MAXPACKET; 155 newchan->recvmaxpacket = RECV_MAXPACKET;
156 156
157 ses.channels[i] = newchan; 157 ses.channels[i] = newchan;
158 ses.chancount++; 158 ses.chancount++;
159 159
160 TRACE(("leave newchannel")); 160 TRACE(("leave newchannel"))
161 161
162 return newchan; 162 return newchan;
163 } 163 }
164 164
165 /* Get the channel structure corresponding to a channel number */ 165 /* Get the channel structure corresponding to a channel number */
244 244
245 245
246 /* do all the EOF/close type stuff checking for a channel */ 246 /* do all the EOF/close type stuff checking for a channel */
247 static void checkclose(struct Channel *channel) { 247 static void checkclose(struct Channel *channel) {
248 248
249 TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d", 249 TRACE(("checkclose: infd %d, outfd %d, errfd %d, sentclosed %d, recvclosed %d",
250 channel->infd, channel->outfd, 250 channel->infd, channel->outfd,
251 channel->errfd, channel->sentclosed, channel->recvclosed)); 251 channel->errfd, channel->sentclosed, channel->recvclosed))
252 TRACE(("writebuf %d extrabuf %s extrabuf %d", 252 TRACE(("writebuf %d extrabuf %s extrabuf %d",
253 cbuf_getused(channel->writebuf), 253 cbuf_getused(channel->writebuf),
254 channel->writebuf, 254 channel->writebuf,
255 channel->writebuf ? 0 : cbuf_getused(channel->extrabuf))); 255 channel->writebuf ? 0 : cbuf_getused(channel->extrabuf)))
256 256
257 if (!channel->sentclosed) { 257 if (!channel->sentclosed) {
258 258
259 /* check for exited - currently only used for server sessions, 259 /* check for exited - currently only used for server sessions,
260 * if the shell has exited etc */ 260 * if the shell has exited etc */
287 * SSH_MSG_CHANNEL_EOF. 287 * SSH_MSG_CHANNEL_EOF.
288 * (from draft-ietf-secsh-connect) 288 * (from draft-ietf-secsh-connect)
289 */ 289 */
290 if (channel->recvclosed) { 290 if (channel->recvclosed) {
291 if (! channel->sentclosed) { 291 if (! channel->sentclosed) {
292 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same.")); 292 TRACE(("Sending MSG_CHANNEL_CLOSE in response to same."))
293 send_msg_channel_close(channel); 293 send_msg_channel_close(channel);
294 } 294 }
295 removechannel(channel); 295 removechannel(channel);
296 } 296 }
297 } 297 }
304 static void checkinitdone(struct Channel *channel) { 304 static void checkinitdone(struct Channel *channel) {
305 305
306 int val; 306 int val;
307 socklen_t vallen = sizeof(val); 307 socklen_t vallen = sizeof(val);
308 308
309 TRACE(("enter checkinitdone")); 309 TRACE(("enter checkinitdone"))
310 310
311 if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen) 311 if (getsockopt(channel->infd, SOL_SOCKET, SO_ERROR, &val, &vallen)
312 || val != 0) { 312 || val != 0) {
313 send_msg_channel_open_failure(channel->remotechan, 313 send_msg_channel_open_failure(channel->remotechan,
314 SSH_OPEN_CONNECT_FAILED, "", ""); 314 SSH_OPEN_CONNECT_FAILED, "", "");
315 close(channel->infd); 315 close(channel->infd);
316 deletechannel(channel); 316 deletechannel(channel);
317 TRACE(("leave checkinitdone: fail")); 317 TRACE(("leave checkinitdone: fail"))
318 } else { 318 } else {
319 send_msg_channel_open_confirmation(channel, channel->recvwindow, 319 send_msg_channel_open_confirmation(channel, channel->recvwindow,
320 channel->recvmaxpacket); 320 channel->recvmaxpacket);
321 channel->outfd = channel->infd; 321 channel->outfd = channel->infd;
322 channel->initconn = 0; 322 channel->initconn = 0;
323 TRACE(("leave checkinitdone: success")); 323 TRACE(("leave checkinitdone: success"))
324 } 324 }
325 } 325 }
326 326
327 327
328 328
329 /* Send the close message and set the channel as closed */ 329 /* Send the close message and set the channel as closed */
330 static void send_msg_channel_close(struct Channel *channel) { 330 static void send_msg_channel_close(struct Channel *channel) {
331 331
332 TRACE(("enter send_msg_channel_close")); 332 TRACE(("enter send_msg_channel_close"))
333 /* XXX server */ 333 /* XXX server */
334 if (channel->type->closehandler) { 334 if (channel->type->closehandler) {
335 channel->type->closehandler(channel); 335 channel->type->closehandler(channel);
336 } 336 }
337 337
342 342
343 encrypt_packet(); 343 encrypt_packet();
344 344
345 channel->senteof = 1; 345 channel->senteof = 1;
346 channel->sentclosed = 1; 346 channel->sentclosed = 1;
347 TRACE(("leave send_msg_channel_close")); 347 TRACE(("leave send_msg_channel_close"))
348 } 348 }
349 349
350 /* call this when trans/eof channels are closed */ 350 /* call this when trans/eof channels are closed */
351 static void send_msg_channel_eof(struct Channel *channel) { 351 static void send_msg_channel_eof(struct Channel *channel) {
352 352
353 TRACE(("enter send_msg_channel_eof")); 353 TRACE(("enter send_msg_channel_eof"))
354 CHECKCLEARTOWRITE(); 354 CHECKCLEARTOWRITE();
355 355
356 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF); 356 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_EOF);
357 buf_putint(ses.writepayload, channel->remotechan); 357 buf_putint(ses.writepayload, channel->remotechan);
358 358
359 encrypt_packet(); 359 encrypt_packet();
360 360
361 channel->senteof = 1; 361 channel->senteof = 1;
362 362
363 TRACE(("leave send_msg_channel_eof")); 363 TRACE(("leave send_msg_channel_eof"))
364 } 364 }
365 365
366 /* Called to write data out to the local side of the channel. 366 /* Called to write data out to the local side of the channel.
367 * Only called when we know we can write to a channel, writes as much as 367 * Only called when we know we can write to a channel, writes as much as
368 * possible */ 368 * possible */
369 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { 369 static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) {
370 370
371 int len, maxlen; 371 int len, maxlen;
372 372
373 TRACE(("enter writechannel")); 373 TRACE(("enter writechannel"))
374 374
375 maxlen = cbuf_readlen(cbuf); 375 maxlen = cbuf_readlen(cbuf);
376 376
377 /* Write the data out */ 377 /* Write the data out */
378 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen); 378 len = write(fd, cbuf_readptr(cbuf, maxlen), maxlen);
380 if (len < 0 && errno != EINTR) { 380 if (len < 0 && errno != EINTR) {
381 /* no more to write - we close it even if the fd was stderr, since 381 /* no more to write - we close it even if the fd was stderr, since
382 * that's a nasty failure too */ 382 * that's a nasty failure too */
383 closeinfd(channel); 383 closeinfd(channel);
384 } 384 }
385 TRACE(("leave writechannel: len <= 0")); 385 TRACE(("leave writechannel: len <= 0"))
386 return; 386 return;
387 } 387 }
388 388
389 cbuf_incrread(cbuf, len); 389 cbuf_incrread(cbuf, len);
390 channel->recvdonelen += len; 390 channel->recvdonelen += len;
391 391
392 if (fd == channel->infd && len == maxlen && channel->recveof) { 392 if (fd == channel->infd && len == maxlen && channel->recveof) {
393 /* Check if we're closing up */ 393 /* Check if we're closing up */
394 closeinfd(channel); 394 closeinfd(channel);
395 TRACE(("leave writechannel: recveof set")); 395 TRACE(("leave writechannel: recveof set"))
396 return; 396 return;
397 } 397 }
398 398
399 /* Window adjust handling */ 399 /* Window adjust handling */
400 if (channel->recvdonelen >= RECV_WINDOWEXTEND) { 400 if (channel->recvdonelen >= RECV_WINDOWEXTEND) {
408 assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); 408 assert(channel->recvwindow <= cbuf_getavail(channel->writebuf));
409 assert(channel->extrabuf == NULL || 409 assert(channel->extrabuf == NULL ||
410 channel->recvwindow <= cbuf_getavail(channel->extrabuf)); 410 channel->recvwindow <= cbuf_getavail(channel->extrabuf));
411 411
412 412
413 TRACE(("leave writechannel")); 413 TRACE(("leave writechannel"))
414 } 414 }
415 415
416 /* Set the file descriptors for the main select in session.c 416 /* Set the file descriptors for the main select in session.c
417 * This avoid channels which don't have any window available, are closed, etc*/ 417 * This avoid channels which don't have any window available, are closed, etc*/
418 void setchannelfds(fd_set *readfd, fd_set *writefd) { 418 void setchannelfds(fd_set *readfd, fd_set *writefd) {
442 /* For checking FD status (ie closure etc) - we don't actually 442 /* For checking FD status (ie closure etc) - we don't actually
443 * read data from infd */ 443 * read data from infd */
444 TRACE(("infd = %d, outfd %d, errfd %d, bufused %d", 444 TRACE(("infd = %d, outfd %d, errfd %d, bufused %d",
445 channel->infd, channel->outfd, 445 channel->infd, channel->outfd,
446 channel->errfd, 446 channel->errfd,
447 cbuf_getused(channel->writebuf) )); 447 cbuf_getused(channel->writebuf) ))
448 if (channel->infd >= 0 && channel->infd != channel->outfd) { 448 if (channel->infd >= 0 && channel->infd != channel->outfd) {
449 FD_SET(channel->infd, readfd); 449 FD_SET(channel->infd, readfd);
450 } 450 }
451 451
452 /* Stuff from the wire, to local program/shell/user etc */ 452 /* Stuff from the wire, to local program/shell/user etc */
475 void recv_msg_channel_eof() { 475 void recv_msg_channel_eof() {
476 476
477 unsigned int chan; 477 unsigned int chan;
478 struct Channel * channel; 478 struct Channel * channel;
479 479
480 TRACE(("enter recv_msg_channel_eof")); 480 TRACE(("enter recv_msg_channel_eof"))
481 481
482 chan = buf_getint(ses.payload); 482 chan = buf_getint(ses.payload);
483 channel = getchannel(chan); 483 channel = getchannel(chan);
484 484
485 if (channel == NULL) { 485 if (channel == NULL) {
491 && (channel->extrabuf == NULL 491 && (channel->extrabuf == NULL
492 || cbuf_getused(channel->extrabuf) == 0)) { 492 || cbuf_getused(channel->extrabuf) == 0)) {
493 closeinfd(channel); 493 closeinfd(channel);
494 } 494 }
495 495
496 TRACE(("leave recv_msg_channel_eof")); 496 TRACE(("leave recv_msg_channel_eof"))
497 } 497 }
498 498
499 499
500 /* Handle channel closure(), respond in kind and close the channels */ 500 /* Handle channel closure(), respond in kind and close the channels */
501 void recv_msg_channel_close() { 501 void recv_msg_channel_close() {
502 502
503 unsigned int chan; 503 unsigned int chan;
504 struct Channel * channel; 504 struct Channel * channel;
505 505
506 TRACE(("enter recv_msg_channel_close")); 506 TRACE(("enter recv_msg_channel_close"))
507 507
508 chan = buf_getint(ses.payload); 508 chan = buf_getint(ses.payload);
509 TRACE(("close channel = %d", chan)); 509 TRACE(("close channel = %d", chan))
510 channel = getchannel(chan); 510 channel = getchannel(chan);
511 511
512 if (channel == NULL) { 512 if (channel == NULL) {
513 /* disconnect ? */ 513 /* disconnect ? */
514 dropbear_exit("Close for unknown channel"); 514 dropbear_exit("Close for unknown channel");
519 519
520 if (channel->sentclosed) { 520 if (channel->sentclosed) {
521 removechannel(channel); 521 removechannel(channel);
522 } 522 }
523 523
524 TRACE(("leave recv_msg_channel_close")); 524 TRACE(("leave recv_msg_channel_close"))
525 } 525 }
526 526
527 /* Remove a channel entry, this is only executed after both sides have sent 527 /* Remove a channel entry, this is only executed after both sides have sent
528 * channel close */ 528 * channel close */
529 static void removechannel(struct Channel * channel) { 529 static void removechannel(struct Channel * channel) {
530 530
531 TRACE(("enter removechannel")); 531 TRACE(("enter removechannel"))
532 TRACE(("channel index is %d", channel->index)); 532 TRACE(("channel index is %d", channel->index))
533 533
534 cbuf_free(channel->writebuf); 534 cbuf_free(channel->writebuf);
535 channel->writebuf = NULL; 535 channel->writebuf = NULL;
536 536
537 if (channel->extrabuf) { 537 if (channel->extrabuf) {
548 548
549 channel->typedata = NULL; 549 channel->typedata = NULL;
550 550
551 deletechannel(channel); 551 deletechannel(channel);
552 552
553 TRACE(("leave removechannel")); 553 TRACE(("leave removechannel"))
554 } 554 }
555 555
556 /* Remove a channel entry */ 556 /* Remove a channel entry */
557 static void deletechannel(struct Channel *channel) { 557 static void deletechannel(struct Channel *channel) {
558 558
568 void recv_msg_channel_request() { 568 void recv_msg_channel_request() {
569 569
570 unsigned int chan; 570 unsigned int chan;
571 struct Channel *channel; 571 struct Channel *channel;
572 572
573 TRACE(("enter recv_msg_channel_request")); 573 TRACE(("enter recv_msg_channel_request"))
574 574
575 chan = buf_getint(ses.payload); 575 chan = buf_getint(ses.payload);
576 channel = getchannel(chan); 576 channel = getchannel(chan);
577 577
578 if (channel == NULL) { 578 if (channel == NULL) {
584 channel->type->reqhandler(channel); 584 channel->type->reqhandler(channel);
585 } else { 585 } else {
586 send_msg_channel_failure(channel); 586 send_msg_channel_failure(channel);
587 } 587 }
588 588
589 TRACE(("leave recv_msg_channel_request")); 589 TRACE(("leave recv_msg_channel_request"))
590 590
591 } 591 }
592 592
593 /* Reads data from the server's program/shell/etc, and puts it in a 593 /* Reads data from the server's program/shell/etc, and puts it in a
594 * channel_data packet to send. 594 * channel_data packet to send.
601 buffer *buf; 601 buffer *buf;
602 int len; 602 int len;
603 unsigned int maxlen; 603 unsigned int maxlen;
604 int fd; 604 int fd;
605 605
606 /* TRACE(("enter send_msg_channel_data")); 606 /* TRACE(("enter send_msg_channel_data"))
607 TRACE(("extended = %d type = %d", isextended, exttype));*/ 607 TRACE(("extended = %d type = %d", isextended, exttype))*/
608 608
609 CHECKCLEARTOWRITE(); 609 CHECKCLEARTOWRITE();
610 610
611 assert(!channel->sentclosed); 611 assert(!channel->sentclosed);
612 612
621 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and 621 /* -(1+4+4) is SSH_MSG_CHANNEL_DATA, channel number, string length, and
622 * exttype if is extended */ 622 * exttype if is extended */
623 maxlen = MIN(maxlen, 623 maxlen = MIN(maxlen,
624 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0)); 624 ses.writepayload->size - 1 - 4 - 4 - (isextended ? 4 : 0));
625 if (maxlen == 0) { 625 if (maxlen == 0) {
626 TRACE(("leave send_msg_channel_data: no window")); 626 TRACE(("leave send_msg_channel_data: no window"))
627 return; /* the data will get written later */ 627 return; /* the data will get written later */
628 } 628 }
629 629
630 /* read the data */ 630 /* read the data */
631 TRACE(("maxlen %d", maxlen)); 631 TRACE(("maxlen %d", maxlen))
632 buf = buf_new(maxlen); 632 buf = buf_new(maxlen);
633 TRACE(("buf pos %d data %x", buf->pos, buf->data)); 633 TRACE(("buf pos %d data %x", buf->pos, buf->data))
634 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen); 634 len = read(fd, buf_getwriteptr(buf, maxlen), maxlen);
635 if (len <= 0) { 635 if (len <= 0) {
636 /* on error/eof, send eof */ 636 /* on error/eof, send eof */
637 if (len == 0 || errno != EINTR) { 637 if (len == 0 || errno != EINTR) {
638 closeoutfd(channel, fd); 638 closeoutfd(channel, fd);
658 buf = NULL; 658 buf = NULL;
659 659
660 channel->transwindow -= len; 660 channel->transwindow -= len;
661 661
662 encrypt_packet(); 662 encrypt_packet();
663 TRACE(("leave send_msg_channel_data")); 663 TRACE(("leave send_msg_channel_data"))
664 } 664 }
665 665
666 /* We receive channel data */ 666 /* We receive channel data */
667 void recv_msg_channel_data() { 667 void recv_msg_channel_data() {
668 668
687 unsigned int datalen; 687 unsigned int datalen;
688 unsigned int maxdata; 688 unsigned int maxdata;
689 unsigned int buflen; 689 unsigned int buflen;
690 unsigned int len; 690 unsigned int len;
691 691
692 TRACE(("enter recv_msg_channel_data")); 692 TRACE(("enter recv_msg_channel_data"))
693 693
694 if (channel->recveof) { 694 if (channel->recveof) {
695 dropbear_exit("received data after eof"); 695 dropbear_exit("received data after eof");
696 } 696 }
697 697
728 728
729 assert(channel->recvwindow >= datalen); 729 assert(channel->recvwindow >= datalen);
730 channel->recvwindow -= datalen; 730 channel->recvwindow -= datalen;
731 assert(channel->recvwindow <= RECV_MAXWINDOW); 731 assert(channel->recvwindow <= RECV_MAXWINDOW);
732 732
733 TRACE(("leave recv_msg_channel_data")); 733 TRACE(("leave recv_msg_channel_data"))
734 } 734 }
735 735
736 /* Increment the outgoing data window for a channel - the remote end limits 736 /* Increment the outgoing data window for a channel - the remote end limits
737 * the amount of data which may be transmitted, this window is decremented 737 * the amount of data which may be transmitted, this window is decremented
738 * as data is sent, and incremented upon receiving window-adjust messages */ 738 * as data is sent, and incremented upon receiving window-adjust messages */
748 if (channel == NULL) { 748 if (channel == NULL) {
749 dropbear_exit("Unknown channel"); 749 dropbear_exit("Unknown channel");
750 } 750 }
751 751
752 incr = buf_getint(ses.payload); 752 incr = buf_getint(ses.payload);
753 TRACE(("received window increment %d", incr)); 753 TRACE(("received window increment %d", incr))
754 incr = MIN(incr, MAX_TRANS_WIN_INCR); 754 incr = MIN(incr, MAX_TRANS_WIN_INCR);
755 755
756 channel->transwindow += incr; 756 channel->transwindow += incr;
757 channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW); 757 channel->transwindow = MIN(channel->transwindow, MAX_TRANS_WINDOW);
758 758
761 /* Increment the incoming data window for a channel, and let the remote 761 /* Increment the incoming data window for a channel, and let the remote
762 * end know */ 762 * end know */
763 static void send_msg_channel_window_adjust(struct Channel* channel, 763 static void send_msg_channel_window_adjust(struct Channel* channel,
764 unsigned int incr) { 764 unsigned int incr) {
765 765
766 TRACE(("sending window adjust %d", incr)); 766 TRACE(("sending window adjust %d", incr))
767 CHECKCLEARTOWRITE(); 767 CHECKCLEARTOWRITE();
768 768
769 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST); 769 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_WINDOW_ADJUST);
770 buf_putint(ses.writepayload, channel->remotechan); 770 buf_putint(ses.writepayload, channel->remotechan);
771 buf_putint(ses.writepayload, incr); 771 buf_putint(ses.writepayload, incr);
785 const struct ChanType *chantype; 785 const struct ChanType *chantype;
786 unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE; 786 unsigned int errtype = SSH_OPEN_UNKNOWN_CHANNEL_TYPE;
787 int ret; 787 int ret;
788 788
789 789
790 TRACE(("enter recv_msg_channel_open")); 790 TRACE(("enter recv_msg_channel_open"))
791 791
792 /* get the packet contents */ 792 /* get the packet contents */
793 type = buf_getstring(ses.payload, &typelen); 793 type = buf_getstring(ses.payload, &typelen);
794 794
795 remotechan = buf_getint(ses.payload); 795 remotechan = buf_getint(ses.payload);
813 break; 813 break;
814 } 814 }
815 } 815 }
816 816
817 if (chantype == NULL) { 817 if (chantype == NULL) {
818 TRACE(("No matching type for '%s'", type)); 818 TRACE(("No matching type for '%s'", type))
819 goto failure; 819 goto failure;
820 } 820 }
821 821
822 TRACE(("matched type '%s'", type)); 822 TRACE(("matched type '%s'", type))
823 823
824 /* create the channel */ 824 /* create the channel */
825 channel = newchannel(remotechan, chantype, transwindow, transmaxpacket); 825 channel = newchannel(remotechan, chantype, transwindow, transmaxpacket);
826 826
827 if (channel == NULL) { 827 if (channel == NULL) {
828 TRACE(("newchannel returned NULL")); 828 TRACE(("newchannel returned NULL"))
829 goto failure; 829 goto failure;
830 } 830 }
831 831
832 if (channel->type->inithandler) { 832 if (channel->type->inithandler) {
833 ret = channel->type->inithandler(channel); 833 ret = channel->type->inithandler(channel);
836 /* We'll send the confirmation later */ 836 /* We'll send the confirmation later */
837 goto cleanup; 837 goto cleanup;
838 } 838 }
839 errtype = ret; 839 errtype = ret;
840 deletechannel(channel); 840 deletechannel(channel);
841 TRACE(("inithandler returned failure %d", ret)); 841 TRACE(("inithandler returned failure %d", ret))
842 goto failure; 842 goto failure;
843 } 843 }
844 } 844 }
845 845
846 /* success */ 846 /* success */
847 send_msg_channel_open_confirmation(channel, channel->recvwindow, 847 send_msg_channel_open_confirmation(channel, channel->recvwindow,
848 channel->recvmaxpacket); 848 channel->recvmaxpacket);
849 goto cleanup; 849 goto cleanup;
850 850
851 failure: 851 failure:
852 TRACE(("recv_msg_channel_open failure")); 852 TRACE(("recv_msg_channel_open failure"))
853 send_msg_channel_open_failure(remotechan, errtype, "", ""); 853 send_msg_channel_open_failure(remotechan, errtype, "", "");
854 854
855 cleanup: 855 cleanup:
856 m_free(type); 856 m_free(type);
857 857
858 TRACE(("leave recv_msg_channel_open")); 858 TRACE(("leave recv_msg_channel_open"))
859 } 859 }
860 860
861 /* Send a failure message */ 861 /* Send a failure message */
862 void send_msg_channel_failure(struct Channel *channel) { 862 void send_msg_channel_failure(struct Channel *channel) {
863 863
864 TRACE(("enter send_msg_channel_failure")); 864 TRACE(("enter send_msg_channel_failure"))
865 CHECKCLEARTOWRITE(); 865 CHECKCLEARTOWRITE();
866 866
867 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE); 867 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_FAILURE);
868 buf_putint(ses.writepayload, channel->remotechan); 868 buf_putint(ses.writepayload, channel->remotechan);
869 869
870 encrypt_packet(); 870 encrypt_packet();
871 TRACE(("leave send_msg_channel_failure")); 871 TRACE(("leave send_msg_channel_failure"))
872 } 872 }
873 873
874 /* Send a success message */ 874 /* Send a success message */
875 void send_msg_channel_success(struct Channel *channel) { 875 void send_msg_channel_success(struct Channel *channel) {
876 876
877 TRACE(("enter send_msg_channel_success")); 877 TRACE(("enter send_msg_channel_success"))
878 CHECKCLEARTOWRITE(); 878 CHECKCLEARTOWRITE();
879 879
880 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS); 880 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_SUCCESS);
881 buf_putint(ses.writepayload, channel->remotechan); 881 buf_putint(ses.writepayload, channel->remotechan);
882 882
883 encrypt_packet(); 883 encrypt_packet();
884 TRACE(("leave send_msg_channel_success")); 884 TRACE(("leave send_msg_channel_success"))
885 } 885 }
886 886
887 /* Send a channel open failure message, with a corresponding reason 887 /* Send a channel open failure message, with a corresponding reason
888 * code (usually resource shortage or unknown chan type) */ 888 * code (usually resource shortage or unknown chan type) */
889 static void send_msg_channel_open_failure(unsigned int remotechan, 889 static void send_msg_channel_open_failure(unsigned int remotechan,
890 int reason, const unsigned char *text, const unsigned char *lang) { 890 int reason, const unsigned char *text, const unsigned char *lang) {
891 891
892 TRACE(("enter send_msg_channel_open_failure")); 892 TRACE(("enter send_msg_channel_open_failure"))
893 CHECKCLEARTOWRITE(); 893 CHECKCLEARTOWRITE();
894 894
895 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE); 895 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_FAILURE);
896 buf_putint(ses.writepayload, remotechan); 896 buf_putint(ses.writepayload, remotechan);
897 buf_putint(ses.writepayload, reason); 897 buf_putint(ses.writepayload, reason);
898 buf_putstring(ses.writepayload, text, strlen((char*)text)); 898 buf_putstring(ses.writepayload, text, strlen((char*)text));
899 buf_putstring(ses.writepayload, lang, strlen((char*)lang)); 899 buf_putstring(ses.writepayload, lang, strlen((char*)lang));
900 900
901 encrypt_packet(); 901 encrypt_packet();
902 TRACE(("leave send_msg_channel_open_failure")); 902 TRACE(("leave send_msg_channel_open_failure"))
903 } 903 }
904 904
905 /* Confirm a channel open, and let the remote end know what number we've 905 /* Confirm a channel open, and let the remote end know what number we've
906 * allocated and the receive parameters */ 906 * allocated and the receive parameters */
907 static void send_msg_channel_open_confirmation(struct Channel* channel, 907 static void send_msg_channel_open_confirmation(struct Channel* channel,
908 unsigned int recvwindow, 908 unsigned int recvwindow,
909 unsigned int recvmaxpacket) { 909 unsigned int recvmaxpacket) {
910 910
911 TRACE(("enter send_msg_channel_open_confirmation")); 911 TRACE(("enter send_msg_channel_open_confirmation"))
912 CHECKCLEARTOWRITE(); 912 CHECKCLEARTOWRITE();
913 913
914 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 914 buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
915 buf_putint(ses.writepayload, channel->remotechan); 915 buf_putint(ses.writepayload, channel->remotechan);
916 buf_putint(ses.writepayload, channel->index); 916 buf_putint(ses.writepayload, channel->index);
917 buf_putint(ses.writepayload, recvwindow); 917 buf_putint(ses.writepayload, recvwindow);
918 buf_putint(ses.writepayload, recvmaxpacket); 918 buf_putint(ses.writepayload, recvmaxpacket);
919 919
920 encrypt_packet(); 920 encrypt_packet();
921 TRACE(("leave send_msg_channel_open_confirmation")); 921 TRACE(("leave send_msg_channel_open_confirmation"))
922 } 922 }
923 923
924 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT) 924 #if defined(USING_LISTENERS) || defined(DROPBEAR_CLIENT)
925 /* Create a new channel, and start the open request. This is intended 925 /* Create a new channel, and start the open request. This is intended
926 * for X11, agent, tcp forwarding, and should be filled with channel-specific 926 * for X11, agent, tcp forwarding, and should be filled with channel-specific
929 * DROPBEAR_SUCCESS is returned */ 929 * DROPBEAR_SUCCESS is returned */
930 int send_msg_channel_open_init(int fd, const struct ChanType *type) { 930 int send_msg_channel_open_init(int fd, const struct ChanType *type) {
931 931
932 struct Channel* chan; 932 struct Channel* chan;
933 933
934 TRACE(("enter send_msg_channel_open_init()")); 934 TRACE(("enter send_msg_channel_open_init()"))
935 chan = newchannel(0, type, 0, 0); 935 chan = newchannel(0, type, 0, 0);
936 if (!chan) { 936 if (!chan) {
937 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()")); 937 TRACE(("leave send_msg_channel_open_init() - FAILED in newchannel()"))
938 return DROPBEAR_FAILURE; 938 return DROPBEAR_FAILURE;
939 } 939 }
940 940
941 /* set fd non-blocking */ 941 /* set fd non-blocking */
942 setnonblocking(fd); 942 setnonblocking(fd);
951 buf_putstring(ses.writepayload, type->name, strlen(type->name)); 951 buf_putstring(ses.writepayload, type->name, strlen(type->name));
952 buf_putint(ses.writepayload, chan->index); 952 buf_putint(ses.writepayload, chan->index);
953 buf_putint(ses.writepayload, RECV_MAXWINDOW); 953 buf_putint(ses.writepayload, RECV_MAXWINDOW);
954 buf_putint(ses.writepayload, RECV_MAXPACKET); 954 buf_putint(ses.writepayload, RECV_MAXPACKET);
955 955
956 TRACE(("leave send_msg_channel_open_init()")); 956 TRACE(("leave send_msg_channel_open_init()"))
957 return DROPBEAR_SUCCESS; 957 return DROPBEAR_SUCCESS;
958 } 958 }
959 959
960 /* Confirmation that our channel open request (for forwardings) was 960 /* Confirmation that our channel open request (for forwardings) was
961 * successful*/ 961 * successful*/
963 963
964 unsigned int chan; 964 unsigned int chan;
965 struct Channel * channel; 965 struct Channel * channel;
966 int ret; 966 int ret;
967 967
968 TRACE(("enter recv_msg_channel_open_confirmation")); 968 TRACE(("enter recv_msg_channel_open_confirmation"))
969 chan = buf_getint(ses.payload); 969 chan = buf_getint(ses.payload);
970 970
971 channel = getchannel(chan); 971 channel = getchannel(chan);
972 if (channel == NULL) { 972 if (channel == NULL) {
973 dropbear_exit("Unknown channel"); 973 dropbear_exit("Unknown channel");
975 975
976 channel->remotechan = buf_getint(ses.payload); 976 channel->remotechan = buf_getint(ses.payload);
977 channel->transwindow = buf_getint(ses.payload); 977 channel->transwindow = buf_getint(ses.payload);
978 channel->transmaxpacket = buf_getint(ses.payload); 978 channel->transmaxpacket = buf_getint(ses.payload);
979 979
980 TRACE(("new chan remote %d localho %d", channel->remotechan, chan)); 980 TRACE(("new chan remote %d localho %d", channel->remotechan, chan))
981 981
982 /* Run the inithandler callback */ 982 /* Run the inithandler callback */
983 if (channel->type->inithandler) { 983 if (channel->type->inithandler) {
984 ret = channel->type->inithandler(channel); 984 ret = channel->type->inithandler(channel);
985 if (ret > 0) { 985 if (ret > 0) {
986 removechannel(channel); 986 removechannel(channel);
987 TRACE(("inithandler returned failure %d", ret)); 987 TRACE(("inithandler returned failure %d", ret))
988 } 988 }
989 } 989 }
990 990
991 991
992 TRACE(("leave recv_msg_channel_open_confirmation")); 992 TRACE(("leave recv_msg_channel_open_confirmation"))
993 } 993 }
994 994
995 /* Notification that our channel open request failed */ 995 /* Notification that our channel open request failed */
996 void recv_msg_channel_open_failure() { 996 void recv_msg_channel_open_failure() {
997 997
1011 /* close a stdout/stderr fd */ 1011 /* close a stdout/stderr fd */
1012 static void closeoutfd(struct Channel * channel, int fd) { 1012 static void closeoutfd(struct Channel * channel, int fd) {
1013 1013
1014 /* don't close it if it is the same as infd, 1014 /* don't close it if it is the same as infd,
1015 * unless infd is already set -1 */ 1015 * unless infd is already set -1 */
1016 TRACE(("enter closeoutfd")); 1016 TRACE(("enter closeoutfd"))
1017 closechanfd(channel, fd, 0); 1017 closechanfd(channel, fd, 0);
1018 TRACE(("leave closeoutfd")); 1018 TRACE(("leave closeoutfd"))
1019 } 1019 }
1020 1020
1021 /* close a stdin fd */ 1021 /* close a stdin fd */
1022 static void closeinfd(struct Channel * channel) { 1022 static void closeinfd(struct Channel * channel) {
1023 1023
1024 TRACE(("enter closeinfd")); 1024 TRACE(("enter closeinfd"))
1025 closechanfd(channel, channel->infd, 1); 1025 closechanfd(channel, channel->infd, 1);
1026 TRACE(("leave closeinfd")); 1026 TRACE(("leave closeinfd"))
1027 } 1027 }
1028 1028
1029 /* close a fd, how is 0 for stdout/stderr, 1 for stdin */ 1029 /* close a fd, how is 0 for stdout/stderr, 1 for stdin */
1030 static void closechanfd(struct Channel *channel, int fd, int how) { 1030 static void closechanfd(struct Channel *channel, int fd, int how) {
1031 1031