summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--channels.c355
-rw-r--r--channels.h22
-rw-r--r--clientloop.c58
-rw-r--r--nchan.c10
-rw-r--r--nchan.h4
-rw-r--r--serverloop.c40
-rw-r--r--ssh.c18
8 files changed, 291 insertions, 223 deletions
diff --git a/ChangeLog b/ChangeLog
index 559347b09..e665f1204 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@
7 [channels.c] 7 [channels.c]
8 channel_new() reallocs channels[], we cannot use Channel *c after calling 8 channel_new() reallocs channels[], we cannot use Channel *c after calling
9 channel_new(), XXX fix this in the future... 9 channel_new(), XXX fix this in the future...
10 - markus@cvs.openbsd.org 2001/05/04 23:47:34
11 [channels.c channels.h clientloop.c nchan.c nchan.h serverloop.c ssh.c]
12 move to Channel **channels (instead of Channel *channels), fixes realloc
13 problems. channel_new now returns a Channel *, favour Channel * over
14 channel id. remove old channel_allocate interface.
10 15
1120010504 1620010504
12 - OpenBSD CVS Sync 17 - OpenBSD CVS Sync
@@ -5337,4 +5342,4 @@
5337 - Wrote replacements for strlcpy and mkdtemp 5342 - Wrote replacements for strlcpy and mkdtemp
5338 - Released 1.0pre1 5343 - Released 1.0pre1
5339 5344
5340$Id: ChangeLog,v 1.1198 2001/05/04 22:40:28 mouring Exp $ 5345$Id: ChangeLog,v 1.1199 2001/05/05 04:09:47 mouring Exp $
diff --git a/channels.c b/channels.c
index 503a81450..2bb0e9851 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.112 2001/05/04 14:34:34 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.113 2001/05/04 23:47:33 markus Exp $");
44 44
45#include <openssl/rsa.h> 45#include <openssl/rsa.h>
46#include <openssl/dsa.h> 46#include <openssl/dsa.h>
@@ -72,18 +72,17 @@ RCSID("$OpenBSD: channels.c,v 1.112 2001/05/04 14:34:34 markus Exp $");
72 * Pointer to an array containing all allocated channels. The array is 72 * Pointer to an array containing all allocated channels. The array is
73 * dynamically extended as needed. 73 * dynamically extended as needed.
74 */ 74 */
75static Channel *channels = NULL; 75static Channel **channels = NULL;
76 76
77/* 77/*
78 * Size of the channel array. All slots of the array must always be 78 * Size of the channel array. All slots of the array must always be
79 * initialized (at least the type field); unused slots are marked with type 79 * initialized (at least the type field); unused slots set to NULL
80 * SSH_CHANNEL_FREE.
81 */ 80 */
82static int channels_alloc = 0; 81static int channels_alloc = 0;
83 82
84/* 83/*
85 * Maximum file descriptor value used in any of the channels. This is 84 * Maximum file descriptor value used in any of the channels. This is
86 * updated in channel_allocate. 85 * updated in channel_new.
87 */ 86 */
88static int channel_max_fd = 0; 87static int channel_max_fd = 0;
89 88
@@ -150,12 +149,13 @@ Channel *
150channel_lookup(int id) 149channel_lookup(int id)
151{ 150{
152 Channel *c; 151 Channel *c;
152
153 if (id < 0 || id > channels_alloc) { 153 if (id < 0 || id > channels_alloc) {
154 log("channel_lookup: %d: bad id", id); 154 log("channel_lookup: %d: bad id", id);
155 return NULL; 155 return NULL;
156 } 156 }
157 c = &channels[id]; 157 c = channels[id];
158 if (c->type == SSH_CHANNEL_FREE) { 158 if (c == NULL) {
159 log("channel_lookup: %d: bad id: channel free", id); 159 log("channel_lookup: %d: bad id: channel free", id);
160 return NULL; 160 return NULL;
161 } 161 }
@@ -212,7 +212,7 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
212 * remote_name to be freed. 212 * remote_name to be freed.
213 */ 213 */
214 214
215int 215Channel *
216channel_new(char *ctype, int type, int rfd, int wfd, int efd, 216channel_new(char *ctype, int type, int rfd, int wfd, int efd,
217 int window, int maxpack, int extusage, char *remote_name, int nonblock) 217 int window, int maxpack, int extusage, char *remote_name, int nonblock)
218{ 218{
@@ -223,9 +223,9 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
223 if (channels_alloc == 0) { 223 if (channels_alloc == 0) {
224 chan_init(); 224 chan_init();
225 channels_alloc = 10; 225 channels_alloc = 10;
226 channels = xmalloc(channels_alloc * sizeof(Channel)); 226 channels = xmalloc(channels_alloc * sizeof(Channel *));
227 for (i = 0; i < channels_alloc; i++) 227 for (i = 0; i < channels_alloc; i++)
228 channels[i].type = SSH_CHANNEL_FREE; 228 channels[i] = NULL;
229 /* 229 /*
230 * Kludge: arrange a call to channel_stop_listening if we 230 * Kludge: arrange a call to channel_stop_listening if we
231 * terminate with fatal(). 231 * terminate with fatal().
@@ -234,7 +234,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
234 } 234 }
235 /* Try to find a free slot where to put the new channel. */ 235 /* Try to find a free slot where to put the new channel. */
236 for (found = -1, i = 0; i < channels_alloc; i++) 236 for (found = -1, i = 0; i < channels_alloc; i++)
237 if (channels[i].type == SSH_CHANNEL_FREE) { 237 if (channels[i] == NULL) {
238 /* Found a free slot. */ 238 /* Found a free slot. */
239 found = i; 239 found = i;
240 break; 240 break;
@@ -244,12 +244,12 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
244 found = channels_alloc; 244 found = channels_alloc;
245 channels_alloc += 10; 245 channels_alloc += 10;
246 debug2("channel: expanding %d", channels_alloc); 246 debug2("channel: expanding %d", channels_alloc);
247 channels = xrealloc(channels, channels_alloc * sizeof(Channel)); 247 channels = xrealloc(channels, channels_alloc * sizeof(Channel *));
248 for (i = found; i < channels_alloc; i++) 248 for (i = found; i < channels_alloc; i++)
249 channels[i].type = SSH_CHANNEL_FREE; 249 channels[i] = NULL;
250 } 250 }
251 /* Initialize and return new channel number. */ 251 /* Initialize and return new channel. */
252 c = &channels[found]; 252 c = channels[found] = xmalloc(sizeof(Channel));
253 buffer_init(&c->input); 253 buffer_init(&c->input);
254 buffer_init(&c->output); 254 buffer_init(&c->output);
255 buffer_init(&c->extended); 255 buffer_init(&c->extended);
@@ -272,16 +272,9 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
272 c->dettach_user = NULL; 272 c->dettach_user = NULL;
273 c->input_filter = NULL; 273 c->input_filter = NULL;
274 debug("channel %d: new [%s]", found, remote_name); 274 debug("channel %d: new [%s]", found, remote_name);
275 return found; 275 return c;
276}
277/* old interface XXX */
278int
279channel_allocate(int type, int sock, char *remote_name)
280{
281 return channel_new("", type, sock, sock, -1, 0, 0, 0, remote_name, 1);
282} 276}
283 277
284
285/* Close all channel fd/socket. */ 278/* Close all channel fd/socket. */
286 279
287void 280void
@@ -308,18 +301,16 @@ channel_close_fds(Channel *c)
308/* Free the channel and close its fd/socket. */ 301/* Free the channel and close its fd/socket. */
309 302
310void 303void
311channel_free(int id) 304channel_free(Channel *c)
312{ 305{
313 Channel *c = channel_lookup(id); 306 char *s;
314 char *s = channel_open_message();
315 307
316 if (c == NULL) 308 s = channel_open_message();
317 packet_disconnect("channel free: bad local channel %d", id); 309 debug("channel_free: channel %d: status: %s", c->self, s);
318 debug("channel_free: channel %d: status: %s", id, s);
319 xfree(s); 310 xfree(s);
320 311
321 if (c->dettach_user != NULL) { 312 if (c->dettach_user != NULL) {
322 debug("channel_free: channel %d: dettaching channel user", id); 313 debug("channel_free: channel %d: dettaching channel user", c->self);
323 c->dettach_user(c->self, NULL); 314 c->dettach_user(c->self, NULL);
324 } 315 }
325 if (c->sock != -1) 316 if (c->sock != -1)
@@ -328,11 +319,12 @@ channel_free(int id)
328 buffer_free(&c->input); 319 buffer_free(&c->input);
329 buffer_free(&c->output); 320 buffer_free(&c->output);
330 buffer_free(&c->extended); 321 buffer_free(&c->extended);
331 c->type = SSH_CHANNEL_FREE;
332 if (c->remote_name) { 322 if (c->remote_name) {
333 xfree(c->remote_name); 323 xfree(c->remote_name);
334 c->remote_name = NULL; 324 c->remote_name = NULL;
335 } 325 }
326 channels[c->self] = NULL;
327 xfree(c);
336} 328}
337 329
338/* 330/*
@@ -428,7 +420,7 @@ void
428channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) 420channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
429{ 421{
430 if (buffer_len(&c->output) == 0) 422 if (buffer_len(&c->output) == 0)
431 channel_free(c->self); 423 chan_mark_dead(c);
432 else 424 else
433 FD_SET(c->sock, writeset); 425 FD_SET(c->sock, writeset);
434} 426}
@@ -640,7 +632,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
640 break; 632 break;
641 } 633 }
642 if (ret < 0) { 634 if (ret < 0) {
643 channel_free(c->self); 635 chan_mark_dead(c);
644 } else if (ret == 0) { 636 } else if (ret == 0) {
645 debug2("channel %d: pre_dynamic: need more", c->self); 637 debug2("channel %d: pre_dynamic: need more", c->self);
646 /* need more */ 638 /* need more */
@@ -656,8 +648,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
656void 648void
657channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) 649channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
658{ 650{
651 Channel *nc;
659 struct sockaddr addr; 652 struct sockaddr addr;
660 int newsock, newch, oldch; 653 int newsock;
661 socklen_t addrlen; 654 socklen_t addrlen;
662 char buf[16384], *remote_ipaddr; 655 char buf[16384], *remote_ipaddr;
663 int remote_port; 656 int remote_port;
@@ -675,16 +668,19 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
675 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d", 668 snprintf(buf, sizeof buf, "X11 connection from %.200s port %d",
676 remote_ipaddr, remote_port); 669 remote_ipaddr, remote_port);
677 670
678 oldch = c->self; 671 nc = channel_new("accepted x11 socket",
679 newch = channel_new("x11",
680 SSH_CHANNEL_OPENING, newsock, newsock, -1, 672 SSH_CHANNEL_OPENING, newsock, newsock, -1,
681 c->local_window_max, c->local_maxpacket, 673 c->local_window_max, c->local_maxpacket,
682 0, xstrdup(buf), 1); 674 0, xstrdup(buf), 1);
683 c = channel_lookup(oldch); 675 if (nc == NULL) {
676 close(newsock);
677 xfree(remote_ipaddr);
678 return;
679 }
684 if (compat20) { 680 if (compat20) {
685 packet_start(SSH2_MSG_CHANNEL_OPEN); 681 packet_start(SSH2_MSG_CHANNEL_OPEN);
686 packet_put_cstring("x11"); 682 packet_put_cstring("x11");
687 packet_put_int(newch); 683 packet_put_int(nc->self);
688 packet_put_int(c->local_window_max); 684 packet_put_int(c->local_window_max);
689 packet_put_int(c->local_maxpacket); 685 packet_put_int(c->local_maxpacket);
690 /* originator ipaddr and port */ 686 /* originator ipaddr and port */
@@ -697,7 +693,7 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
697 packet_send(); 693 packet_send();
698 } else { 694 } else {
699 packet_start(SSH_SMSG_X11_OPEN); 695 packet_start(SSH_SMSG_X11_OPEN);
700 packet_put_int(newch); 696 packet_put_int(nc->self);
701 if (have_hostname_in_open) 697 if (have_hostname_in_open)
702 packet_put_string(buf, strlen(buf)); 698 packet_put_string(buf, strlen(buf));
703 packet_send(); 699 packet_send();
@@ -764,7 +760,7 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
764{ 760{
765 Channel *nc; 761 Channel *nc;
766 struct sockaddr addr; 762 struct sockaddr addr;
767 int newsock, newch, nextstate, oldch; 763 int newsock, nextstate;
768 socklen_t addrlen; 764 socklen_t addrlen;
769 char *rtype; 765 char *rtype;
770 766
@@ -784,16 +780,13 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
784 error("accept: %.100s", strerror(errno)); 780 error("accept: %.100s", strerror(errno));
785 return; 781 return;
786 } 782 }
787 oldch = c->self; 783 nc = channel_new(rtype,
788 newch = channel_new(rtype,
789 nextstate, newsock, newsock, -1, 784 nextstate, newsock, newsock, -1,
790 c->local_window_max, c->local_maxpacket, 785 c->local_window_max, c->local_maxpacket,
791 0, xstrdup(rtype), 1); 786 0, xstrdup(rtype), 1);
792
793 c = channel_lookup(oldch);
794 nc = channel_lookup(newch);
795 if (nc == NULL) { 787 if (nc == NULL) {
796 error("xxx: no new channel:"); 788 error("channel_post_port_listener: no new channel:");
789 close(newsock);
797 return; 790 return;
798 } 791 }
799 nc->listening_port = c->listening_port; 792 nc->listening_port = c->listening_port;
@@ -812,8 +805,9 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
812void 805void
813channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) 806channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
814{ 807{
808 Channel *nc;
809 int newsock;
815 struct sockaddr addr; 810 struct sockaddr addr;
816 int newsock, newch, oldch;
817 socklen_t addrlen; 811 socklen_t addrlen;
818 812
819 if (FD_ISSET(c->sock, readset)) { 813 if (FD_ISSET(c->sock, readset)) {
@@ -823,21 +817,23 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
823 error("accept from auth socket: %.100s", strerror(errno)); 817 error("accept from auth socket: %.100s", strerror(errno));
824 return; 818 return;
825 } 819 }
826 oldch = c->self; 820 nc = channel_new("accepted auth socket",
827 newch = channel_new("accepted auth socket",
828 SSH_CHANNEL_OPENING, newsock, newsock, -1, 821 SSH_CHANNEL_OPENING, newsock, newsock, -1,
829 c->local_window_max, c->local_maxpacket, 822 c->local_window_max, c->local_maxpacket,
830 0, xstrdup("accepted auth socket"), 1); 823 0, xstrdup("accepted auth socket"), 1);
831 c = channel_lookup(oldch); 824 if (nc == NULL) {
825 error("channel_post_auth_listener: channel_new failed");
826 close(newsock);
827 }
832 if (compat20) { 828 if (compat20) {
833 packet_start(SSH2_MSG_CHANNEL_OPEN); 829 packet_start(SSH2_MSG_CHANNEL_OPEN);
834 packet_put_cstring("auth-agent@openssh.com"); 830 packet_put_cstring("auth-agent@openssh.com");
835 packet_put_int(newch); 831 packet_put_int(nc->self);
836 packet_put_int(c->local_window_max); 832 packet_put_int(c->local_window_max);
837 packet_put_int(c->local_maxpacket); 833 packet_put_int(c->local_maxpacket);
838 } else { 834 } else {
839 packet_start(SSH_SMSG_AGENT_OPEN); 835 packet_start(SSH_SMSG_AGENT_OPEN);
840 packet_put_int(newch); 836 packet_put_int(nc->self);
841 } 837 }
842 packet_send(); 838 packet_send();
843 } 839 }
@@ -881,7 +877,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
881 c->self, c->rfd, len); 877 c->self, c->rfd, len);
882 if (c->type != SSH_CHANNEL_OPEN) { 878 if (c->type != SSH_CHANNEL_OPEN) {
883 debug("channel %d: not open", c->self); 879 debug("channel %d: not open", c->self);
884 channel_free(c->self); 880 chan_mark_dead(c);
885 return -1; 881 return -1;
886 } else if (compat13) { 882 } else if (compat13) {
887 buffer_consume(&c->output, buffer_len(&c->output)); 883 buffer_consume(&c->output, buffer_len(&c->output));
@@ -920,7 +916,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
920 if (len <= 0) { 916 if (len <= 0) {
921 if (c->type != SSH_CHANNEL_OPEN) { 917 if (c->type != SSH_CHANNEL_OPEN) {
922 debug("channel %d: not open", c->self); 918 debug("channel %d: not open", c->self);
923 channel_free(c->self); 919 chan_mark_dead(c);
924 return -1; 920 return -1;
925 } else if (compat13) { 921 } else if (compat13) {
926 buffer_consume(&c->output, buffer_len(&c->output)); 922 buffer_consume(&c->output, buffer_len(&c->output));
@@ -1138,13 +1134,12 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1138 did_init = 1; 1134 did_init = 1;
1139 } 1135 }
1140 for (i = 0; i < channels_alloc; i++) { 1136 for (i = 0; i < channels_alloc; i++) {
1141 c = &channels[i]; 1137 c = channels[i];
1142 if (c->type == SSH_CHANNEL_FREE) 1138 if (c == NULL)
1143 continue; 1139 continue;
1144 if (ftab[c->type] == NULL) 1140 if (ftab[c->type] == NULL)
1145 continue; 1141 continue;
1146 (*ftab[c->type])(c, readset, writeset); 1142 (*ftab[c->type])(c, readset, writeset);
1147 c = &channels[i]; /* XXX realloc */
1148 if (chan_is_dead(c)) { 1143 if (chan_is_dead(c)) {
1149 /* 1144 /*
1150 * we have to remove the fd's from the select mask 1145 * we have to remove the fd's from the select mask
@@ -1161,7 +1156,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1161 if (c->extended_usage == CHAN_EXTENDED_WRITE) 1156 if (c->extended_usage == CHAN_EXTENDED_WRITE)
1162 FD_CLR(c->efd, writeset); 1157 FD_CLR(c->efd, writeset);
1163 } 1158 }
1164 channel_free(c->self); 1159 channel_free(c);
1165 } 1160 }
1166 } 1161 }
1167} 1162}
@@ -1207,7 +1202,10 @@ channel_output_poll()
1207 Channel *c; 1202 Channel *c;
1208 1203
1209 for (i = 0; i < channels_alloc; i++) { 1204 for (i = 0; i < channels_alloc; i++) {
1210 c = &channels[i]; 1205
1206 c = channels[i];
1207 if (c == NULL)
1208 continue;
1211 1209
1212 /* We are only interested in channels that can have buffered incoming data. */ 1210 /* We are only interested in channels that can have buffered incoming data. */
1213 if (compat13) { 1211 if (compat13) {
@@ -1391,8 +1389,8 @@ channel_not_very_much_buffered_data()
1391 Channel *c; 1389 Channel *c;
1392 1390
1393 for (i = 0; i < channels_alloc; i++) { 1391 for (i = 0; i < channels_alloc; i++) {
1394 c = &channels[i]; 1392 c = channels[i];
1395 if (c->type == SSH_CHANNEL_OPEN) { 1393 if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
1396 if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) { 1394 if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {
1397 debug("channel %d: big input buffer %d", 1395 debug("channel %d: big input buffer %d",
1398 c->self, buffer_len(&c->input)); 1396 c->self, buffer_len(&c->input));
@@ -1486,7 +1484,7 @@ channel_input_close_confirmation(int type, int plen, void *ctxt)
1486 if (c->type != SSH_CHANNEL_CLOSED) 1484 if (c->type != SSH_CHANNEL_CLOSED)
1487 packet_disconnect("Received close confirmation for " 1485 packet_disconnect("Received close confirmation for "
1488 "non-closed channel %d (type %d).", id, c->type); 1486 "non-closed channel %d (type %d).", id, c->type);
1489 channel_free(c->self); 1487 channel_free(c);
1490} 1488}
1491 1489
1492void 1490void
@@ -1554,7 +1552,7 @@ channel_input_open_failure(int type, int plen, void *ctxt)
1554 xfree(lang); 1552 xfree(lang);
1555 } 1553 }
1556 /* Free the channel. This will also close the socket. */ 1554 /* Free the channel. This will also close the socket. */
1557 channel_free(id); 1555 channel_free(c);
1558} 1556}
1559 1557
1560void 1558void
@@ -1615,21 +1613,26 @@ void
1615channel_stop_listening() 1613channel_stop_listening()
1616{ 1614{
1617 int i; 1615 int i;
1616 Channel *c;
1617
1618 for (i = 0; i < channels_alloc; i++) { 1618 for (i = 0; i < channels_alloc; i++) {
1619 switch (channels[i].type) { 1619 c = channels[i];
1620 case SSH_CHANNEL_AUTH_SOCKET: 1620 if (c != NULL) {
1621 close(channels[i].sock); 1621 switch (c->type) {
1622 unlink(channels[i].path); 1622 case SSH_CHANNEL_AUTH_SOCKET:
1623 channel_free(i); 1623 close(c->sock);
1624 break; 1624 unlink(c->path);
1625 case SSH_CHANNEL_PORT_LISTENER: 1625 channel_free(c);
1626 case SSH_CHANNEL_RPORT_LISTENER: 1626 break;
1627 case SSH_CHANNEL_X11_LISTENER: 1627 case SSH_CHANNEL_PORT_LISTENER:
1628 close(channels[i].sock); 1628 case SSH_CHANNEL_RPORT_LISTENER:
1629 channel_free(i); 1629 case SSH_CHANNEL_X11_LISTENER:
1630 break; 1630 close(c->sock);
1631 default: 1631 channel_free(c);
1632 break; 1632 break;
1633 default:
1634 break;
1635 }
1633 } 1636 }
1634 } 1637 }
1635} 1638}
@@ -1643,9 +1646,10 @@ void
1643channel_close_all() 1646channel_close_all()
1644{ 1647{
1645 int i; 1648 int i;
1649
1646 for (i = 0; i < channels_alloc; i++) 1650 for (i = 0; i < channels_alloc; i++)
1647 if (channels[i].type != SSH_CHANNEL_FREE) 1651 if (channels[i] != NULL)
1648 channel_close_fds(&channels[i]); 1652 channel_close_fds(channels[i]);
1649} 1653}
1650 1654
1651/* Returns true if any channel is still open. */ 1655/* Returns true if any channel is still open. */
@@ -1653,10 +1657,14 @@ channel_close_all()
1653int 1657int
1654channel_still_open() 1658channel_still_open()
1655{ 1659{
1656 u_int i; 1660 int i;
1657 for (i = 0; i < channels_alloc; i++) 1661 Channel *c;
1658 switch (channels[i].type) { 1662
1659 case SSH_CHANNEL_FREE: 1663 for (i = 0; i < channels_alloc; i++) {
1664 c = channels[i];
1665 if (c == NULL)
1666 continue;
1667 switch (c->type) {
1660 case SSH_CHANNEL_X11_LISTENER: 1668 case SSH_CHANNEL_X11_LISTENER:
1661 case SSH_CHANNEL_PORT_LISTENER: 1669 case SSH_CHANNEL_PORT_LISTENER:
1662 case SSH_CHANNEL_RPORT_LISTENER: 1670 case SSH_CHANNEL_RPORT_LISTENER:
@@ -1679,9 +1687,10 @@ channel_still_open()
1679 fatal("cannot happen: OUT_DRAIN"); 1687 fatal("cannot happen: OUT_DRAIN");
1680 return 1; 1688 return 1;
1681 default: 1689 default:
1682 fatal("channel_still_open: bad channel type %d", channels[i].type); 1690 fatal("channel_still_open: bad channel type %d", c->type);
1683 /* NOTREACHED */ 1691 /* NOTREACHED */
1684 } 1692 }
1693 }
1685 return 0; 1694 return 0;
1686} 1695}
1687 1696
@@ -1690,12 +1699,16 @@ channel_still_open()
1690int 1699int
1691channel_find_open() 1700channel_find_open()
1692{ 1701{
1693 u_int i; 1702 int i;
1694 for (i = 0; i < channels_alloc; i++) 1703 Channel *c;
1695 switch (channels[i].type) { 1704
1705 for (i = 0; i < channels_alloc; i++) {
1706 c = channels[i];
1707 if (c == NULL)
1708 continue;
1709 switch (c->type) {
1696 case SSH_CHANNEL_CLOSED: 1710 case SSH_CHANNEL_CLOSED:
1697 case SSH_CHANNEL_DYNAMIC: 1711 case SSH_CHANNEL_DYNAMIC:
1698 case SSH_CHANNEL_FREE:
1699 case SSH_CHANNEL_X11_LISTENER: 1712 case SSH_CHANNEL_X11_LISTENER:
1700 case SSH_CHANNEL_PORT_LISTENER: 1713 case SSH_CHANNEL_PORT_LISTENER:
1701 case SSH_CHANNEL_RPORT_LISTENER: 1714 case SSH_CHANNEL_RPORT_LISTENER:
@@ -1713,9 +1726,10 @@ channel_find_open()
1713 fatal("cannot happen: OUT_DRAIN"); 1726 fatal("cannot happen: OUT_DRAIN");
1714 return i; 1727 return i;
1715 default: 1728 default:
1716 fatal("channel_find_open: bad channel type %d", channels[i].type); 1729 fatal("channel_find_open: bad channel type %d", c->type);
1717 /* NOTREACHED */ 1730 /* NOTREACHED */
1718 } 1731 }
1732 }
1719 return -1; 1733 return -1;
1720} 1734}
1721 1735
@@ -1730,16 +1744,18 @@ char *
1730channel_open_message() 1744channel_open_message()
1731{ 1745{
1732 Buffer buffer; 1746 Buffer buffer;
1747 Channel *c;
1748 char buf[1024], *cp;
1733 int i; 1749 int i;
1734 char buf[512], *cp;
1735 1750
1736 buffer_init(&buffer); 1751 buffer_init(&buffer);
1737 snprintf(buf, sizeof buf, "The following connections are open:\r\n"); 1752 snprintf(buf, sizeof buf, "The following connections are open:\r\n");
1738 buffer_append(&buffer, buf, strlen(buf)); 1753 buffer_append(&buffer, buf, strlen(buf));
1739 for (i = 0; i < channels_alloc; i++) { 1754 for (i = 0; i < channels_alloc; i++) {
1740 Channel *c = &channels[i]; 1755 c = channels[i];
1756 if (c == NULL)
1757 continue;
1741 switch (c->type) { 1758 switch (c->type) {
1742 case SSH_CHANNEL_FREE:
1743 case SSH_CHANNEL_X11_LISTENER: 1759 case SSH_CHANNEL_X11_LISTENER:
1744 case SSH_CHANNEL_PORT_LISTENER: 1760 case SSH_CHANNEL_PORT_LISTENER:
1745 case SSH_CHANNEL_RPORT_LISTENER: 1761 case SSH_CHANNEL_RPORT_LISTENER:
@@ -1797,7 +1813,8 @@ channel_request_forwarding(
1797 const char *host_to_connect, u_short port_to_connect, 1813 const char *host_to_connect, u_short port_to_connect,
1798 int gateway_ports, int remote_fwd) 1814 int gateway_ports, int remote_fwd)
1799{ 1815{
1800 int success, ch, sock, on = 1, ctype; 1816 Channel *c;
1817 int success, sock, on = 1, ctype;
1801 struct addrinfo hints, *ai, *aitop; 1818 struct addrinfo hints, *ai, *aitop;
1802 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 1819 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1803 const char *host; 1820 const char *host;
@@ -1813,7 +1830,7 @@ channel_request_forwarding(
1813 ctype =SSH_CHANNEL_PORT_LISTENER; 1830 ctype =SSH_CHANNEL_PORT_LISTENER;
1814 } 1831 }
1815 1832
1816 if (strlen(host) > sizeof(channels[0].path) - 1) { 1833 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
1817 error("Forward host name too long."); 1834 error("Forward host name too long.");
1818 return success; 1835 return success;
1819 } 1836 }
@@ -1874,12 +1891,17 @@ channel_request_forwarding(
1874 continue; 1891 continue;
1875 } 1892 }
1876 /* Allocate a channel number for the socket. */ 1893 /* Allocate a channel number for the socket. */
1877 ch = channel_new("port listener", ctype, sock, sock, -1, 1894 c = channel_new("port listener", ctype, sock, sock, -1,
1878 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 1895 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1879 0, xstrdup("port listener"), 1); 1896 0, xstrdup("port listener"), 1);
1880 strlcpy(channels[ch].path, host, sizeof(channels[ch].path)); 1897 if (c == NULL) {
1881 channels[ch].host_port = port_to_connect; 1898 error("channel_request_forwarding: channel_new failed");
1882 channels[ch].listening_port = listen_port; 1899 close(sock);
1900 continue;
1901 }
1902 strlcpy(c->path, host, sizeof(c->path));
1903 c->host_port = port_to_connect;
1904 c->listening_port = listen_port;
1883 success = 1; 1905 success = 1;
1884 } 1906 }
1885 if (success == 0) 1907 if (success == 0)
@@ -2116,11 +2138,12 @@ channel_connect_to(const char *host, u_short port)
2116void 2138void
2117channel_input_port_open(int type, int plen, void *ctxt) 2139channel_input_port_open(int type, int plen, void *ctxt)
2118{ 2140{
2141 Channel *c = NULL;
2119 u_short host_port; 2142 u_short host_port;
2120 char *host, *originator_string; 2143 char *host, *originator_string;
2121 int remote_channel, sock = -1, newch; 2144 int remote_id, sock = -1;
2122 2145
2123 remote_channel = packet_get_int(); 2146 remote_id = packet_get_int();
2124 host = packet_get_string(NULL); 2147 host = packet_get_string(NULL);
2125 host_port = packet_get_int(); 2148 host_port = packet_get_int();
2126 2149
@@ -2132,20 +2155,26 @@ channel_input_port_open(int type, int plen, void *ctxt)
2132 packet_done(); 2155 packet_done();
2133 sock = channel_connect_to(host, host_port); 2156 sock = channel_connect_to(host, host_port);
2134 if (sock != -1) { 2157 if (sock != -1) {
2135 newch = channel_allocate(SSH_CHANNEL_CONNECTING, 2158 c = channel_new("connected socket",
2136 sock, originator_string); 2159 SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
2137 channels[newch].remote_id = remote_channel; 2160 originator_string, 1);
2138 2161 if (c == NULL) {
2162 error("channel_input_port_open: channel_new failed");
2163 close(sock);
2164 } else {
2165 c->remote_id = remote_id;
2166 }
2167 }
2168 if (c == NULL) {
2169 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2170 packet_put_int(remote_id);
2171 } else {
2139 /*XXX delay answer? */ 2172 /*XXX delay answer? */
2140 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 2173 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2141 packet_put_int(remote_channel); 2174 packet_put_int(remote_id);
2142 packet_put_int(newch); 2175 packet_put_int(c->self);
2143 packet_send();
2144 } else {
2145 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2146 packet_put_int(remote_channel);
2147 packet_send();
2148 } 2176 }
2177 packet_send();
2149 xfree(host); 2178 xfree(host);
2150} 2179}
2151 2180
@@ -2430,46 +2459,45 @@ x11_connect_display(void)
2430void 2459void
2431x11_input_open(int type, int plen, void *ctxt) 2460x11_input_open(int type, int plen, void *ctxt)
2432{ 2461{
2433 int remote_channel, sock = 0, newch; 2462 Channel *c = NULL;
2463 int remote_id, sock = 0;
2434 char *remote_host; 2464 char *remote_host;
2435 u_int remote_len;
2436 2465
2437 /* Get remote channel number. */ 2466 debug("Received X11 open request.");
2438 remote_channel = packet_get_int();
2439 2467
2440 /* Get remote originator name. */ 2468 remote_id = packet_get_int();
2441 if (have_hostname_in_open) { 2469 if (have_hostname_in_open) {
2442 remote_host = packet_get_string(&remote_len); 2470 remote_host = packet_get_string(NULL);
2443 remote_len += 4;
2444 } else { 2471 } else {
2445 remote_host = xstrdup("unknown (remote did not supply name)"); 2472 remote_host = xstrdup("unknown (remote did not supply name)");
2446 remote_len = 0;
2447 } 2473 }
2448 2474 packet_done();
2449 debug("Received X11 open request.");
2450 packet_integrity_check(plen, 4 + remote_len, SSH_SMSG_X11_OPEN);
2451 2475
2452 /* Obtain a connection to the real X display. */ 2476 /* Obtain a connection to the real X display. */
2453 sock = x11_connect_display(); 2477 sock = x11_connect_display();
2454 if (sock == -1) { 2478 if (sock != -1) {
2479 /* Allocate a channel for this connection. */
2480 c = channel_new("connected x11 socket",
2481 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 0, 0, 0,
2482 remote_host, 1);
2483 if (c == NULL) {
2484 error("x11_input_open: channel_new failed");
2485 close(sock);
2486 } else {
2487 c->remote_id = remote_id;
2488 }
2489 }
2490 if (c == NULL) {
2455 /* Send refusal to the remote host. */ 2491 /* Send refusal to the remote host. */
2456 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 2492 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2457 packet_put_int(remote_channel); 2493 packet_put_int(remote_id);
2458 packet_send();
2459 } else { 2494 } else {
2460 /* Allocate a channel for this connection. */
2461 newch = channel_allocate(
2462 (x11_saved_proto == NULL) ?
2463 SSH_CHANNEL_OPEN : SSH_CHANNEL_X11_OPEN,
2464 sock, remote_host);
2465 channels[newch].remote_id = remote_channel;
2466
2467 /* Send a confirmation to the remote host. */ 2495 /* Send a confirmation to the remote host. */
2468 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION); 2496 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2469 packet_put_int(remote_channel); 2497 packet_put_int(remote_id);
2470 packet_put_int(newch); 2498 packet_put_int(c->self);
2471 packet_send();
2472 } 2499 }
2500 packet_send();
2473} 2501}
2474 2502
2475/* dummy protocol handler that denies SSH-1 requests (agent/x11) */ 2503/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
@@ -2602,7 +2630,8 @@ cleanup_socket(void)
2602int 2630int
2603auth_input_request_forwarding(struct passwd * pw) 2631auth_input_request_forwarding(struct passwd * pw)
2604{ 2632{
2605 int sock, newch; 2633 Channel *nc;
2634 int sock;
2606 struct sockaddr_un sunaddr; 2635 struct sockaddr_un sunaddr;
2607 2636
2608 if (auth_get_socket_name() != NULL) 2637 if (auth_get_socket_name() != NULL)
@@ -2657,13 +2686,16 @@ auth_input_request_forwarding(struct passwd * pw)
2657 packet_disconnect("listen: %.100s", strerror(errno)); 2686 packet_disconnect("listen: %.100s", strerror(errno));
2658 2687
2659 /* Allocate a channel for the authentication agent socket. */ 2688 /* Allocate a channel for the authentication agent socket. */
2660 newch = channel_new("auth socket", 2689 nc = channel_new("auth socket",
2661 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, 2690 SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
2662 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 2691 CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
2663 0, xstrdup("auth socket"), 1); 2692 0, xstrdup("auth socket"), 1);
2664 2693 if (nc == NULL) {
2665 strlcpy(channels[newch].path, channel_forwarded_auth_socket_name, 2694 error("auth_input_request_forwarding: channel_new failed");
2666 sizeof(channels[newch].path)); 2695 close(sock);
2696 return 0;
2697 }
2698 strlcpy(nc->path, channel_forwarded_auth_socket_name, sizeof(nc->path));
2667 return 1; 2699 return 1;
2668} 2700}
2669 2701
@@ -2672,13 +2704,14 @@ auth_input_request_forwarding(struct passwd * pw)
2672void 2704void
2673auth_input_open_request(int type, int plen, void *ctxt) 2705auth_input_open_request(int type, int plen, void *ctxt)
2674{ 2706{
2675 int remch, sock, newch; 2707 Channel *c = NULL;
2708 int remote_id, sock;
2676 char *dummyname; 2709 char *dummyname;
2677 2710
2678 packet_integrity_check(plen, 4, type); 2711 packet_integrity_check(plen, 4, type);
2679 2712
2680 /* Read the remote channel number from the message. */ 2713 /* Read the remote channel number from the message. */
2681 remch = packet_get_int(); 2714 remote_id = packet_get_int();
2682 2715
2683 /* 2716 /*
2684 * Get a connection to the local authentication agent (this may again 2717 * Get a connection to the local authentication agent (this may again
@@ -2692,28 +2725,26 @@ auth_input_open_request(int type, int plen, void *ctxt)
2692 * because authentication forwarding is only enabled if we have an 2725 * because authentication forwarding is only enabled if we have an
2693 * agent. 2726 * agent.
2694 */ 2727 */
2695 if (sock < 0) { 2728 if (sock >= 0) {
2729 dummyname = xstrdup("authentication agent connection");
2730 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, -1, 0, 0, 0, dummyname, 1);
2731 if (c == NULL) {
2732 error("auth_input_open_request: channel_new failed");
2733 close(sock);
2734 } else {
2735 c->remote_id = remote_id;
2736 }
2737 }
2738 if (c == NULL) {
2696 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE); 2739 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2697 packet_put_int(remch); 2740 packet_put_int(remote_id);
2698 packet_send(); 2741 } else {
2699 return; 2742 /* Send a confirmation to the remote host. */
2743 debug("Forwarding authentication connection.");
2744 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2745 packet_put_int(remote_id);
2746 packet_put_int(c->self);
2700 } 2747 }
2701 debug("Forwarding authentication connection.");
2702
2703 /*
2704 * Dummy host name. This will be freed when the channel is freed; it
2705 * will still be valid in the packet_put_string below since the
2706 * channel cannot yet be freed at that point.
2707 */
2708 dummyname = xstrdup("authentication agent connection");
2709
2710 newch = channel_allocate(SSH_CHANNEL_OPEN, sock, dummyname);
2711 channels[newch].remote_id = remch;
2712
2713 /* Send a confirmation to the remote host. */
2714 packet_start(SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
2715 packet_put_int(remch);
2716 packet_put_int(newch);
2717 packet_send(); 2748 packet_send();
2718} 2749}
2719 2750
diff --git a/channels.h b/channels.h
index bf70a8f21..6739b2214 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.31 2001/04/13 22:46:53 beck Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.32 2001/05/04 23:47:33 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNELS_H
38#define CHANNELS_H 38#define CHANNELS_H
@@ -40,7 +40,6 @@
40#include "buffer.h" 40#include "buffer.h"
41 41
42/* Definitions for channel types. */ 42/* Definitions for channel types. */
43#define SSH_CHANNEL_FREE 0 /* This channel is free (unused). */
44#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */ 43#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
45#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */ 44#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
46#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */ 45#define SSH_CHANNEL_OPENING 3 /* waiting for confirmation */
@@ -56,8 +55,10 @@
56#define SSH_CHANNEL_DYNAMIC 13 55#define SSH_CHANNEL_DYNAMIC 13
57#define SSH_CHANNEL_MAX_TYPE 14 56#define SSH_CHANNEL_MAX_TYPE 14
58 57
58#define SSH_CHANNEL_PATH_LEN 30
59
59/* 60/*
60 * Data structure for channel data. This is iniailized in channel_allocate 61 * Data structure for channel data. This is initialized in channel_new
61 * and cleared in channel_free. 62 * and cleared in channel_free.
62 */ 63 */
63struct Channel; 64struct Channel;
@@ -84,8 +85,8 @@ struct Channel {
84 Buffer output; /* data received over encrypted connection for 85 Buffer output; /* data received over encrypted connection for
85 * send on socket */ 86 * send on socket */
86 Buffer extended; 87 Buffer extended;
87 char path[200]; /* path for unix domain sockets, or host name 88 char path[SSH_CHANNEL_PATH_LEN];
88 * for forwards */ 89 /* path for unix domain sockets, or host name for forwards */
89 int listening_port; /* port being listened for forwards */ 90 int listening_port; /* port being listened for forwards */
90 int host_port; /* remote port to connect for forwards */ 91 int host_port; /* remote port to connect for forwards */
91 char *remote_name; /* remote hostname */ 92 char *remote_name; /* remote hostname */
@@ -132,10 +133,6 @@ void channel_register_filter(int id, channel_filter_fn *fn);
132void channel_cancel_cleanup(int id); 133void channel_cancel_cleanup(int id);
133Channel *channel_lookup(int id); 134Channel *channel_lookup(int id);
134 135
135int
136channel_new(char *ctype, int type, int rfd, int wfd, int efd,
137 int window, int maxpack, int extended_usage, char *remote_name,
138 int nonblock);
139void 136void
140channel_set_fds(int id, int rfd, int wfd, int efd, 137channel_set_fds(int id, int rfd, int wfd, int efd,
141 int extusage, int nonblock); 138 int extusage, int nonblock);
@@ -162,10 +159,13 @@ void channel_set_options(int hostname_in_open);
162 * must have been allocated with xmalloc; this will free it when the channel 159 * must have been allocated with xmalloc; this will free it when the channel
163 * is freed. 160 * is freed.
164 */ 161 */
165int channel_allocate(int type, int sock, char *remote_name); 162Channel *
163channel_new(char *ctype, int type, int rfd, int wfd, int efd,
164 int window, int maxpack, int extended_usage, char *remote_name,
165 int nonblock);
166 166
167/* Free the channel and close its socket. */ 167/* Free the channel and close its socket. */
168void channel_free(int channel); 168void channel_free(Channel *c);
169 169
170/* 170/*
171 * Allocate/update select bitmasks and add any bits relevant to channels in 171 * Allocate/update select bitmasks and add any bits relevant to channels in
diff --git a/clientloop.c b/clientloop.c
index d76189738..2bc5b54aa 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.66 2001/04/29 19:16:52 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.67 2001/05/04 23:47:34 markus Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -1027,7 +1027,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
1027 Channel* c = NULL; 1027 Channel* c = NULL;
1028 char *listen_address, *originator_address; 1028 char *listen_address, *originator_address;
1029 int listen_port, originator_port; 1029 int listen_port, originator_port;
1030 int sock, newch; 1030 int sock;
1031 1031
1032 /* Get rest of the packet */ 1032 /* Get rest of the packet */
1033 listen_address = packet_get_string(NULL); 1033 listen_address = packet_get_string(NULL);
@@ -1040,12 +1040,18 @@ client_request_forwarded_tcpip(const char *request_type, int rchan)
1040 listen_address, listen_port, originator_address, originator_port); 1040 listen_address, listen_port, originator_address, originator_port);
1041 1041
1042 sock = channel_connect_by_listen_adress(listen_port); 1042 sock = channel_connect_by_listen_adress(listen_port);
1043 if (sock >= 0) { 1043 if (sock < 0) {
1044 newch = channel_new("forwarded-tcpip", 1044 xfree(originator_address);
1045 SSH_CHANNEL_CONNECTING, sock, sock, -1, 1045 xfree(listen_address);
1046 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1046 return NULL;
1047 xstrdup(originator_address), 1); 1047 }
1048 c = channel_lookup(newch); 1048 c = channel_new("forwarded-tcpip",
1049 SSH_CHANNEL_CONNECTING, sock, sock, -1,
1050 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1051 xstrdup(originator_address), 1);
1052 if (c == NULL) {
1053 error("client_request_forwarded_tcpip: channel_new failed");
1054 close(sock);
1049 } 1055 }
1050 xfree(originator_address); 1056 xfree(originator_address);
1051 xfree(listen_address); 1057 xfree(listen_address);
@@ -1058,7 +1064,7 @@ client_request_x11(const char *request_type, int rchan)
1058 Channel *c = NULL; 1064 Channel *c = NULL;
1059 char *originator; 1065 char *originator;
1060 int originator_port; 1066 int originator_port;
1061 int sock, newch; 1067 int sock;
1062 1068
1063 if (!options.forward_x11) { 1069 if (!options.forward_x11) {
1064 error("Warning: ssh server tried X11 forwarding."); 1070 error("Warning: ssh server tried X11 forwarding.");
@@ -1076,15 +1082,18 @@ client_request_x11(const char *request_type, int rchan)
1076 /* XXX check permission */ 1082 /* XXX check permission */
1077 debug("client_request_x11: request from %s %d", originator, 1083 debug("client_request_x11: request from %s %d", originator,
1078 originator_port); 1084 originator_port);
1085 xfree(originator);
1079 sock = x11_connect_display(); 1086 sock = x11_connect_display();
1080 if (sock >= 0) { 1087 if (sock < 0)
1081 newch = channel_new("x11", 1088 return NULL;
1082 SSH_CHANNEL_X11_OPEN, sock, sock, -1, 1089 c = channel_new("x11",
1083 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, 1090 SSH_CHANNEL_X11_OPEN, sock, sock, -1,
1084 xstrdup("x11"), 1); 1091 CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
1085 c = channel_lookup(newch); 1092 xstrdup("x11"), 1);
1093 if (c == NULL) {
1094 error("client_request_x11: channel_new failed");
1095 close(sock);
1086 } 1096 }
1087 xfree(originator);
1088 return c; 1097 return c;
1089} 1098}
1090 1099
@@ -1092,7 +1101,7 @@ Channel*
1092client_request_agent(const char *request_type, int rchan) 1101client_request_agent(const char *request_type, int rchan)
1093{ 1102{
1094 Channel *c = NULL; 1103 Channel *c = NULL;
1095 int sock, newch; 1104 int sock;
1096 1105
1097 if (!options.forward_agent) { 1106 if (!options.forward_agent) {
1098 error("Warning: ssh server tried agent forwarding."); 1107 error("Warning: ssh server tried agent forwarding.");
@@ -1100,12 +1109,15 @@ client_request_agent(const char *request_type, int rchan)
1100 return NULL; 1109 return NULL;
1101 } 1110 }
1102 sock = ssh_get_authentication_socket(); 1111 sock = ssh_get_authentication_socket();
1103 if (sock >= 0) { 1112 if (sock < 0)
1104 newch = channel_new("authentication agent connection", 1113 return NULL;
1105 SSH_CHANNEL_OPEN, sock, sock, -1, 1114 c = channel_new("authentication agent connection",
1106 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0, 1115 SSH_CHANNEL_OPEN, sock, sock, -1,
1107 xstrdup("authentication agent connection"), 1); 1116 CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
1108 c = channel_lookup(newch); 1117 xstrdup("authentication agent connection"), 1);
1118 if (c == NULL) {
1119 error("client_request_agent: channel_new failed");
1120 close(sock);
1109 } 1121 }
1110 return c; 1122 return c;
1111} 1123}
diff --git a/nchan.c b/nchan.c
index 77e4ef486..f4606e07f 100644
--- a/nchan.c
+++ b/nchan.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $"); 26RCSID("$OpenBSD: nchan.c,v 1.24 2001/05/04 23:47:34 markus Exp $");
27 27
28#include "ssh1.h" 28#include "ssh1.h"
29#include "ssh2.h" 29#include "ssh2.h"
@@ -391,9 +391,17 @@ chan_send_close2(Channel *c)
391 391
392/* shared */ 392/* shared */
393 393
394void
395chan_mark_dead(Channel *c)
396{
397 c->flags |= CHAN_DEAD;
398}
399
394int 400int
395chan_is_dead(Channel *c) 401chan_is_dead(Channel *c)
396{ 402{
403 if (c->flags & CHAN_DEAD)
404 return 1;
397 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED) 405 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
398 return 0; 406 return 0;
399 if (!compat20) { 407 if (!compat20) {
diff --git a/nchan.h b/nchan.h
index 623ecccc3..db04973f4 100644
--- a/nchan.h
+++ b/nchan.h
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24 24
25/* RCSID("$OpenBSD: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */ 25/* RCSID("$OpenBSD: nchan.h,v 1.11 2001/05/04 23:47:34 markus Exp $"); */
26 26
27#ifndef NCHAN_H 27#ifndef NCHAN_H
28#define NCHAN_H 28#define NCHAN_H
@@ -69,6 +69,7 @@
69 69
70#define CHAN_CLOSE_SENT 0x01 70#define CHAN_CLOSE_SENT 0x01
71#define CHAN_CLOSE_RCVD 0x02 71#define CHAN_CLOSE_RCVD 0x02
72#define CHAN_DEAD 0x04
72 73
73 74
74/* Channel EVENTS */ 75/* Channel EVENTS */
@@ -85,6 +86,7 @@ extern chan_event_fn *chan_write_failed;
85extern chan_event_fn *chan_obuf_empty; 86extern chan_event_fn *chan_obuf_empty;
86 87
87int chan_is_dead(Channel * c); 88int chan_is_dead(Channel * c);
89void chan_mark_dead(Channel * c);
88 90
89void chan_init_iostates(Channel * c); 91void chan_init_iostates(Channel * c);
90void chan_init(void); 92void chan_init(void);
diff --git a/serverloop.c b/serverloop.c
index 2ca892e5d..5b3135564 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.63 2001/04/29 19:16:52 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.64 2001/05/04 23:47:34 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -801,7 +801,8 @@ server_input_window_size(int type, int plen, void *ctxt)
801Channel * 801Channel *
802server_request_direct_tcpip(char *ctype) 802server_request_direct_tcpip(char *ctype)
803{ 803{
804 int sock, newch; 804 Channel *c;
805 int sock;
805 char *target, *originator; 806 char *target, *originator;
806 int target_port, originator_port; 807 int target_port, originator_port;
807 808
@@ -820,16 +821,20 @@ server_request_direct_tcpip(char *ctype)
820 xfree(originator); 821 xfree(originator);
821 if (sock < 0) 822 if (sock < 0)
822 return NULL; 823 return NULL;
823 newch = channel_new(ctype, SSH_CHANNEL_CONNECTING, 824 c = channel_new(ctype, SSH_CHANNEL_CONNECTING,
824 sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, 825 sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
825 CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1); 826 CHAN_TCP_PACKET_DEFAULT, 0, xstrdup("direct-tcpip"), 1);
826 return (newch >= 0) ? channel_lookup(newch) : NULL; 827 if (c == NULL) {
828 error("server_request_direct_tcpip: channel_new failed");
829 close(sock);
830 }
831 return c;
827} 832}
828 833
829Channel * 834Channel *
830server_request_session(char *ctype) 835server_request_session(char *ctype)
831{ 836{
832 int newch; 837 Channel *c;
833 838
834 debug("input_session_request"); 839 debug("input_session_request");
835 packet_done(); 840 packet_done();
@@ -839,19 +844,22 @@ server_request_session(char *ctype)
839 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all 844 * SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
840 * CHANNEL_REQUEST messages is registered. 845 * CHANNEL_REQUEST messages is registered.
841 */ 846 */
842 newch = channel_new(ctype, SSH_CHANNEL_LARVAL, 847 c = channel_new(ctype, SSH_CHANNEL_LARVAL,
843 -1, -1, -1, 0, CHAN_SES_PACKET_DEFAULT, 848 -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
844 0, xstrdup("server-session"), 1); 849 0, xstrdup("server-session"), 1);
845 if (session_open(newch) == 1) { 850 if (c == NULL) {
846 channel_register_callback(newch, SSH2_MSG_CHANNEL_REQUEST, 851 error("server_request_session: channel_new failed");
847 session_input_channel_req, (void *)0); 852 return NULL;
848 channel_register_cleanup(newch, session_close_by_channel); 853 }
849 return channel_lookup(newch); 854 if (session_open(c->self) != 1) {
850 } else { 855 debug("session open failed, free channel %d", c->self);
851 debug("session open failed, free channel %d", newch); 856 channel_free(c);
852 channel_free(newch); 857 return NULL;
853 } 858 }
854 return NULL; 859 channel_register_callback(c->self, SSH2_MSG_CHANNEL_REQUEST,
860 session_input_channel_req, (void *)0);
861 channel_register_cleanup(c->self, session_close_by_channel);
862 return c;
855} 863}
856 864
857void 865void
diff --git a/ssh.c b/ssh.c
index 0ba69be53..c2932582f 100644
--- a/ssh.c
+++ b/ssh.c
@@ -39,7 +39,7 @@
39 */ 39 */
40 40
41#include "includes.h" 41#include "includes.h"
42RCSID("$OpenBSD: ssh.c,v 1.117 2001/04/30 11:18:52 markus Exp $"); 42RCSID("$OpenBSD: ssh.c,v 1.118 2001/05/04 23:47:34 markus Exp $");
43 43
44#include <openssl/evp.h> 44#include <openssl/evp.h>
45#include <openssl/err.h> 45#include <openssl/err.h>
@@ -1058,8 +1058,8 @@ ssh_session2_callback(int id, void *arg)
1058int 1058int
1059ssh_session2_command(void) 1059ssh_session2_command(void)
1060{ 1060{
1061 int id, window, packetmax; 1061 Channel *c;
1062 int in, out, err; 1062 int window, packetmax, in, out, err;
1063 1063
1064 if (stdin_null_flag) { 1064 if (stdin_null_flag) {
1065 in = open(_PATH_DEVNULL, O_RDONLY); 1065 in = open(_PATH_DEVNULL, O_RDONLY);
@@ -1086,18 +1086,20 @@ ssh_session2_command(void)
1086 window *= 2; 1086 window *= 2;
1087 packetmax *=2; 1087 packetmax *=2;
1088 } 1088 }
1089 id = channel_new( 1089 c = channel_new(
1090 "session", SSH_CHANNEL_OPENING, in, out, err, 1090 "session", SSH_CHANNEL_OPENING, in, out, err,
1091 window, packetmax, CHAN_EXTENDED_WRITE, 1091 window, packetmax, CHAN_EXTENDED_WRITE,
1092 xstrdup("client-session"), /*nonblock*/0); 1092 xstrdup("client-session"), /*nonblock*/0);
1093 if (c == NULL)
1094 fatal("ssh_session2_command: channel_new failed");
1093 1095
1094debug("channel_new: %d", id); 1096 debug3("ssh_session2_command: channel_new: %d", c->self);
1095 1097
1096 channel_open(id); 1098 channel_open(c->self);
1097 channel_register_callback(id, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, 1099 channel_register_callback(c->self, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
1098 ssh_session2_callback, (void *)0); 1100 ssh_session2_callback, (void *)0);
1099 1101
1100 return id; 1102 return c->self;
1101} 1103}
1102 1104
1103int 1105int