diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | channels.c | 355 | ||||
-rw-r--r-- | channels.h | 22 | ||||
-rw-r--r-- | clientloop.c | 58 | ||||
-rw-r--r-- | nchan.c | 10 | ||||
-rw-r--r-- | nchan.h | 4 | ||||
-rw-r--r-- | serverloop.c | 40 | ||||
-rw-r--r-- | ssh.c | 18 |
8 files changed, 291 insertions, 223 deletions
@@ -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 | ||
11 | 20010504 | 16 | 20010504 |
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" |
43 | RCSID("$OpenBSD: channels.c,v 1.112 2001/05/04 14:34:34 markus Exp $"); | 43 | RCSID("$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 | */ |
75 | static Channel *channels = NULL; | 75 | static 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 | */ |
82 | static int channels_alloc = 0; | 81 | static 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 | */ |
88 | static int channel_max_fd = 0; | 87 | static int channel_max_fd = 0; |
89 | 88 | ||
@@ -150,12 +149,13 @@ Channel * | |||
150 | channel_lookup(int id) | 149 | channel_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 | ||
215 | int | 215 | Channel * |
216 | channel_new(char *ctype, int type, int rfd, int wfd, int efd, | 216 | channel_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 */ | ||
278 | int | ||
279 | channel_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 | ||
287 | void | 280 | void |
@@ -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 | ||
310 | void | 303 | void |
311 | channel_free(int id) | 304 | channel_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 | |||
428 | channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset) | 420 | channel_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) | |||
656 | void | 648 | void |
657 | channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset) | 649 | channel_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) | |||
812 | void | 805 | void |
813 | channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) | 806 | channel_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 | ||
1492 | void | 1490 | void |
@@ -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 | ||
1560 | void | 1558 | void |
@@ -1615,21 +1613,26 @@ void | |||
1615 | channel_stop_listening() | 1613 | channel_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 | |||
1643 | channel_close_all() | 1646 | channel_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() | |||
1653 | int | 1657 | int |
1654 | channel_still_open() | 1658 | channel_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() | |||
1690 | int | 1699 | int |
1691 | channel_find_open() | 1700 | channel_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 * | |||
1730 | channel_open_message() | 1744 | channel_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) | |||
2116 | void | 2138 | void |
2117 | channel_input_port_open(int type, int plen, void *ctxt) | 2139 | channel_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) | |||
2430 | void | 2459 | void |
2431 | x11_input_open(int type, int plen, void *ctxt) | 2460 | x11_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) | |||
2602 | int | 2630 | int |
2603 | auth_input_request_forwarding(struct passwd * pw) | 2631 | auth_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) | |||
2672 | void | 2704 | void |
2673 | auth_input_open_request(int type, int plen, void *ctxt) | 2705 | auth_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 | */ |
63 | struct Channel; | 64 | struct 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); | |||
132 | void channel_cancel_cleanup(int id); | 133 | void channel_cancel_cleanup(int id); |
133 | Channel *channel_lookup(int id); | 134 | Channel *channel_lookup(int id); |
134 | 135 | ||
135 | int | ||
136 | channel_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); | ||
139 | void | 136 | void |
140 | channel_set_fds(int id, int rfd, int wfd, int efd, | 137 | channel_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 | */ |
165 | int channel_allocate(int type, int sock, char *remote_name); | 162 | Channel * |
163 | channel_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. */ |
168 | void channel_free(int channel); | 168 | void 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" |
62 | RCSID("$OpenBSD: clientloop.c,v 1.66 2001/04/29 19:16:52 markus Exp $"); | 62 | RCSID("$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* | |||
1092 | client_request_agent(const char *request_type, int rchan) | 1101 | client_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 | } |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $"); | 26 | RCSID("$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 | ||
394 | void | ||
395 | chan_mark_dead(Channel *c) | ||
396 | { | ||
397 | c->flags |= CHAN_DEAD; | ||
398 | } | ||
399 | |||
394 | int | 400 | int |
395 | chan_is_dead(Channel *c) | 401 | chan_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) { |
@@ -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; | |||
85 | extern chan_event_fn *chan_obuf_empty; | 86 | extern chan_event_fn *chan_obuf_empty; |
86 | 87 | ||
87 | int chan_is_dead(Channel * c); | 88 | int chan_is_dead(Channel * c); |
89 | void chan_mark_dead(Channel * c); | ||
88 | 90 | ||
89 | void chan_init_iostates(Channel * c); | 91 | void chan_init_iostates(Channel * c); |
90 | void chan_init(void); | 92 | void 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" |
38 | RCSID("$OpenBSD: serverloop.c,v 1.63 2001/04/29 19:16:52 markus Exp $"); | 38 | RCSID("$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) | |||
801 | Channel * | 801 | Channel * |
802 | server_request_direct_tcpip(char *ctype) | 802 | server_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 | ||
829 | Channel * | 834 | Channel * |
830 | server_request_session(char *ctype) | 835 | server_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 | ||
857 | void | 865 | void |
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.117 2001/04/30 11:18:52 markus Exp $"); | 42 | RCSID("$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) | |||
1058 | int | 1058 | int |
1059 | ssh_session2_command(void) | 1059 | ssh_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 | ||
1094 | debug("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 | ||
1103 | int | 1105 | int |