summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-06-09 00:41:05 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-06-09 00:41:05 +0000
commite9c999137a7b3497a7ad652da2535e14b42c6552 (patch)
tree0cf04fb0298309408f6e021e7291b42f0400c101
parentc763767f18464129f3aa80f00a341f8665cfe53a (diff)
- (bal) Channels.c and Channels.h -- "Merge Functions, simplify" (draged
out of ssh Attic)
-rw-r--r--ChangeLog4
-rw-r--r--channels.c896
-rw-r--r--channels.h185
3 files changed, 518 insertions, 567 deletions
diff --git a/ChangeLog b/ChangeLog
index 4cfdbc7a0..5b5344297 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,8 @@
12 packet.c serverloop.c session.c ssh.c] 12 packet.c serverloop.c session.c ssh.c]
13 undo the .c file split, just merge the header and keep the cvs 13 undo the .c file split, just merge the header and keep the cvs
14 history 14 history
15 - (bal) Channels.c and Channels.h -- "Merge Functions, simplify" (draged
16 out of ssh Attic)
15 17
1620010606 1820010606
17 - OpenBSD CVS Sync 19 - OpenBSD CVS Sync
@@ -5523,4 +5525,4 @@
5523 - Wrote replacements for strlcpy and mkdtemp 5525 - Wrote replacements for strlcpy and mkdtemp
5524 - Released 1.0pre1 5526 - Released 1.0pre1
5525 5527
5526$Id: ChangeLog,v 1.1249 2001/06/09 00:36:26 mouring Exp $ 5528$Id: ChangeLog,v 1.1250 2001/06/09 00:41:05 mouring Exp $
diff --git a/channels.c b/channels.c
index 719dbff53..518a071b8 100644
--- a/channels.c
+++ b/channels.c
@@ -40,33 +40,24 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.119 2001/05/28 23:25:24 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.121 2001/05/31 10:30:14 markus Exp $");
44
45#include <openssl/rsa.h>
46#include <openssl/dsa.h>
47 44
48#include "ssh.h" 45#include "ssh.h"
49#include "ssh1.h" 46#include "ssh1.h"
50#include "ssh2.h" 47#include "ssh2.h"
51#include "packet.h" 48#include "packet.h"
52#include "xmalloc.h" 49#include "xmalloc.h"
53#include "buffer.h"
54#include "bufaux.h"
55#include "uidswap.h" 50#include "uidswap.h"
56#include "log.h" 51#include "log.h"
57#include "misc.h" 52#include "misc.h"
58#include "channels.h" 53#include "channels.h"
59#include "nchan.h"
60#include "compat.h" 54#include "compat.h"
61#include "canohost.h" 55#include "canohost.h"
62#include "key.h" 56#include "key.h"
63#include "authfd.h" 57#include "authfd.h"
64 58
65/* Maximum number of fake X11 displays to try. */
66#define MAX_DISPLAYS 1000
67 59
68/* Max len of agent socket */ 60/* -- channel core */
69#define MAX_SOCKET_NAME 100
70 61
71/* 62/*
72 * Pointer to an array containing all allocated channels. The array is 63 * Pointer to an array containing all allocated channels. The array is
@@ -86,23 +77,8 @@ static int channels_alloc = 0;
86 */ 77 */
87static int channel_max_fd = 0; 78static int channel_max_fd = 0;
88 79
89/* Name and directory of socket for authentication agent forwarding. */
90static char *channel_forwarded_auth_socket_name = NULL;
91static char *channel_forwarded_auth_socket_dir = NULL;
92
93/* Saved X11 authentication protocol name. */
94char *x11_saved_proto = NULL;
95
96/* Saved X11 authentication data. This is the real data. */
97char *x11_saved_data = NULL;
98u_int x11_saved_data_len = 0;
99 80
100/* 81/* -- tcp forwarding */
101 * Fake X11 authentication data. This is what the server will be sending us;
102 * we should replace any occurrences of this by the real data.
103 */
104char *x11_fake_data = NULL;
105u_int x11_fake_data_len;
106 82
107/* 83/*
108 * Data structure for storing which hosts are permitted for forward requests. 84 * Data structure for storing which hosts are permitted for forward requests.
@@ -118,6 +94,7 @@ typedef struct {
118 94
119/* List of all permitted host/port pairs to connect. */ 95/* List of all permitted host/port pairs to connect. */
120static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; 96static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
97
121/* Number of permitted host/port pairs in the array. */ 98/* Number of permitted host/port pairs in the array. */
122static int num_permitted_opens = 0; 99static int num_permitted_opens = 0;
123/* 100/*
@@ -127,23 +104,43 @@ static int num_permitted_opens = 0;
127 */ 104 */
128static int all_opens_permitted = 0; 105static int all_opens_permitted = 0;
129 106
130/* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */
131static int have_hostname_in_open = 0;
132 107
133/* AF_UNSPEC or AF_INET or AF_INET6 */ 108/* -- X11 forwarding */
134extern int IPv4or6;
135 109
136void port_open_helper(Channel *c, char *rtype); 110/* Maximum number of fake X11 displays to try. */
111#define MAX_DISPLAYS 1000
137 112
138/* Sets specific protocol options. */ 113/* Saved X11 authentication protocol name. */
114static char *x11_saved_proto = NULL;
139 115
140void 116/* Saved X11 authentication data. This is the real data. */
141channel_set_options(int hostname_in_open) 117static char *x11_saved_data = NULL;
142{ 118static u_int x11_saved_data_len = 0;
143 have_hostname_in_open = hostname_in_open;
144}
145 119
146/* lookup channel by id */ 120/*
121 * Fake X11 authentication data. This is what the server will be sending us;
122 * we should replace any occurrences of this by the real data.
123 */
124static char *x11_fake_data = NULL;
125static u_int x11_fake_data_len;
126
127
128/* -- agent forwarding */
129
130#define NUM_SOCKS 10
131
132/* Name and directory of socket for authentication agent forwarding. */
133static char *auth_sock_name = NULL;
134static char *auth_sock_dir = NULL;
135
136
137/* AF_UNSPEC or AF_INET or AF_INET6 */
138extern int IPv4or6;
139
140/* helper */
141void port_open_helper(Channel *c, char *rtype);
142
143/* -- channel core */
147 144
148Channel * 145Channel *
149channel_lookup(int id) 146channel_lookup(int id)
@@ -337,6 +334,321 @@ channel_free(Channel *c)
337 xfree(c); 334 xfree(c);
338} 335}
339 336
337
338/*
339 * Stops listening for channels, and removes any unix domain sockets that we
340 * might have.
341 */
342
343void
344channel_stop_listening()
345{
346 int i;
347 Channel *c;
348
349 for (i = 0; i < channels_alloc; i++) {
350 c = channels[i];
351 if (c != NULL) {
352 switch (c->type) {
353 case SSH_CHANNEL_AUTH_SOCKET:
354 close(c->sock);
355 unlink(c->path);
356 channel_free(c);
357 break;
358 case SSH_CHANNEL_PORT_LISTENER:
359 case SSH_CHANNEL_RPORT_LISTENER:
360 case SSH_CHANNEL_X11_LISTENER:
361 close(c->sock);
362 channel_free(c);
363 break;
364 default:
365 break;
366 }
367 }
368 }
369}
370
371/*
372 * Closes the sockets/fds of all channels. This is used to close extra file
373 * descriptors after a fork.
374 */
375
376void
377channel_close_all()
378{
379 int i;
380
381 for (i = 0; i < channels_alloc; i++)
382 if (channels[i] != NULL)
383 channel_close_fds(channels[i]);
384}
385
386/*
387 * Returns true if no channel has too much buffered data, and false if one or
388 * more channel is overfull.
389 */
390
391int
392channel_not_very_much_buffered_data()
393{
394 u_int i;
395 Channel *c;
396
397 for (i = 0; i < channels_alloc; i++) {
398 c = channels[i];
399 if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
400 if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {
401 debug("channel %d: big input buffer %d",
402 c->self, buffer_len(&c->input));
403 return 0;
404 }
405 if (buffer_len(&c->output) > packet_get_maxsize()) {
406 debug("channel %d: big output buffer %d",
407 c->self, buffer_len(&c->output));
408 return 0;
409 }
410 }
411 }
412 return 1;
413}
414
415/* Returns true if any channel is still open. */
416
417int
418channel_still_open()
419{
420 int i;
421 Channel *c;
422
423 for (i = 0; i < channels_alloc; i++) {
424 c = channels[i];
425 if (c == NULL)
426 continue;
427 switch (c->type) {
428 case SSH_CHANNEL_X11_LISTENER:
429 case SSH_CHANNEL_PORT_LISTENER:
430 case SSH_CHANNEL_RPORT_LISTENER:
431 case SSH_CHANNEL_CLOSED:
432 case SSH_CHANNEL_AUTH_SOCKET:
433 case SSH_CHANNEL_DYNAMIC:
434 case SSH_CHANNEL_CONNECTING:
435 case SSH_CHANNEL_ZOMBIE:
436 continue;
437 case SSH_CHANNEL_LARVAL:
438 if (!compat20)
439 fatal("cannot happen: SSH_CHANNEL_LARVAL");
440 continue;
441 case SSH_CHANNEL_OPENING:
442 case SSH_CHANNEL_OPEN:
443 case SSH_CHANNEL_X11_OPEN:
444 return 1;
445 case SSH_CHANNEL_INPUT_DRAINING:
446 case SSH_CHANNEL_OUTPUT_DRAINING:
447 if (!compat13)
448 fatal("cannot happen: OUT_DRAIN");
449 return 1;
450 default:
451 fatal("channel_still_open: bad channel type %d", c->type);
452 /* NOTREACHED */
453 }
454 }
455 return 0;
456}
457
458/* Returns the id of an open channel suitable for keepaliving */
459
460int
461channel_find_open()
462{
463 int i;
464 Channel *c;
465
466 for (i = 0; i < channels_alloc; i++) {
467 c = channels[i];
468 if (c == NULL)
469 continue;
470 switch (c->type) {
471 case SSH_CHANNEL_CLOSED:
472 case SSH_CHANNEL_DYNAMIC:
473 case SSH_CHANNEL_X11_LISTENER:
474 case SSH_CHANNEL_PORT_LISTENER:
475 case SSH_CHANNEL_RPORT_LISTENER:
476 case SSH_CHANNEL_OPENING:
477 case SSH_CHANNEL_CONNECTING:
478 case SSH_CHANNEL_ZOMBIE:
479 continue;
480 case SSH_CHANNEL_LARVAL:
481 case SSH_CHANNEL_AUTH_SOCKET:
482 case SSH_CHANNEL_OPEN:
483 case SSH_CHANNEL_X11_OPEN:
484 return i;
485 case SSH_CHANNEL_INPUT_DRAINING:
486 case SSH_CHANNEL_OUTPUT_DRAINING:
487 if (!compat13)
488 fatal("cannot happen: OUT_DRAIN");
489 return i;
490 default:
491 fatal("channel_find_open: bad channel type %d", c->type);
492 /* NOTREACHED */
493 }
494 }
495 return -1;
496}
497
498
499/*
500 * Returns a message describing the currently open forwarded connections,
501 * suitable for sending to the client. The message contains crlf pairs for
502 * newlines.
503 */
504
505char *
506channel_open_message()
507{
508 Buffer buffer;
509 Channel *c;
510 char buf[1024], *cp;
511 int i;
512
513 buffer_init(&buffer);
514 snprintf(buf, sizeof buf, "The following connections are open:\r\n");
515 buffer_append(&buffer, buf, strlen(buf));
516 for (i = 0; i < channels_alloc; i++) {
517 c = channels[i];
518 if (c == NULL)
519 continue;
520 switch (c->type) {
521 case SSH_CHANNEL_X11_LISTENER:
522 case SSH_CHANNEL_PORT_LISTENER:
523 case SSH_CHANNEL_RPORT_LISTENER:
524 case SSH_CHANNEL_CLOSED:
525 case SSH_CHANNEL_AUTH_SOCKET:
526 case SSH_CHANNEL_ZOMBIE:
527 continue;
528 case SSH_CHANNEL_LARVAL:
529 case SSH_CHANNEL_OPENING:
530 case SSH_CHANNEL_CONNECTING:
531 case SSH_CHANNEL_DYNAMIC:
532 case SSH_CHANNEL_OPEN:
533 case SSH_CHANNEL_X11_OPEN:
534 case SSH_CHANNEL_INPUT_DRAINING:
535 case SSH_CHANNEL_OUTPUT_DRAINING:
536 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",
537 c->self, c->remote_name,
538 c->type, c->remote_id,
539 c->istate, buffer_len(&c->input),
540 c->ostate, buffer_len(&c->output),
541 c->rfd, c->wfd);
542 buffer_append(&buffer, buf, strlen(buf));
543 continue;
544 default:
545 fatal("channel_open_message: bad channel type %d", c->type);
546 /* NOTREACHED */
547 }
548 }
549 buffer_append(&buffer, "\0", 1);
550 cp = xstrdup(buffer_ptr(&buffer));
551 buffer_free(&buffer);
552 return cp;
553}
554
555void
556channel_send_open(int id)
557{
558 Channel *c = channel_lookup(id);
559 if (c == NULL) {
560 log("channel_send_open: %d: bad id", id);
561 return;
562 }
563 debug("send channel open %d", id);
564 packet_start(SSH2_MSG_CHANNEL_OPEN);
565 packet_put_cstring(c->ctype);
566 packet_put_int(c->self);
567 packet_put_int(c->local_window);
568 packet_put_int(c->local_maxpacket);
569 packet_send();
570}
571
572void
573channel_request(int id, char *service, int wantconfirm)
574{
575 channel_request_start(id, service, wantconfirm);
576 packet_send();
577 debug("channel request %d: %s", id, service) ;
578}
579void
580channel_request_start(int id, char *service, int wantconfirm)
581{
582 Channel *c = channel_lookup(id);
583 if (c == NULL) {
584 log("channel_request: %d: bad id", id);
585 return;
586 }
587 packet_start(SSH2_MSG_CHANNEL_REQUEST);
588 packet_put_int(c->remote_id);
589 packet_put_cstring(service);
590 packet_put_char(wantconfirm);
591}
592void
593channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg)
594{
595 Channel *c = channel_lookup(id);
596 if (c == NULL) {
597 log("channel_register_callback: %d: bad id", id);
598 return;
599 }
600 c->cb_event = mtype;
601 c->cb_fn = fn;
602 c->cb_arg = arg;
603}
604void
605channel_register_cleanup(int id, channel_callback_fn *fn)
606{
607 Channel *c = channel_lookup(id);
608 if (c == NULL) {
609 log("channel_register_cleanup: %d: bad id", id);
610 return;
611 }
612 c->dettach_user = fn;
613}
614void
615channel_cancel_cleanup(int id)
616{
617 Channel *c = channel_lookup(id);
618 if (c == NULL) {
619 log("channel_cancel_cleanup: %d: bad id", id);
620 return;
621 }
622 c->dettach_user = NULL;
623}
624void
625channel_register_filter(int id, channel_filter_fn *fn)
626{
627 Channel *c = channel_lookup(id);
628 if (c == NULL) {
629 log("channel_register_filter: %d: bad id", id);
630 return;
631 }
632 c->input_filter = fn;
633}
634
635void
636channel_set_fds(int id, int rfd, int wfd, int efd,
637 int extusage, int nonblock)
638{
639 Channel *c = channel_lookup(id);
640 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
641 fatal("channel_activate for non-larval channel %d.", id);
642 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
643 c->type = SSH_CHANNEL_OPEN;
644 /* XXX window size? */
645 c->local_window = c->local_window_max = c->local_maxpacket * 2;
646 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
647 packet_put_int(c->remote_id);
648 packet_put_int(c->local_window);
649 packet_send();
650}
651
340/* 652/*
341 * 'channel_pre*' are called just before select() to add any bits relevant to 653 * 'channel_pre*' are called just before select() to add any bits relevant to
342 * channels in the select bitmasks. 654 * channels in the select bitmasks.
@@ -442,19 +754,20 @@ channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
442 * data in that packet is then substituted by the real data if it matches the 754 * data in that packet is then substituted by the real data if it matches the
443 * fake data, and the channel is put into normal mode. 755 * fake data, and the channel is put into normal mode.
444 * XXX All this happens at the client side. 756 * XXX All this happens at the client side.
757 * Returns: 0 = need more data, -1 = wrong cookie, 1 = ok
445 */ 758 */
446int 759int
447x11_open_helper(Channel *c) 760x11_open_helper(Buffer *b)
448{ 761{
449 u_char *ucp; 762 u_char *ucp;
450 u_int proto_len, data_len; 763 u_int proto_len, data_len;
451 764
452 /* Check if the fixed size part of the packet is in buffer. */ 765 /* Check if the fixed size part of the packet is in buffer. */
453 if (buffer_len(&c->output) < 12) 766 if (buffer_len(b) < 12)
454 return 0; 767 return 0;
455 768
456 /* Parse the lengths of variable-length fields. */ 769 /* Parse the lengths of variable-length fields. */
457 ucp = (u_char *) buffer_ptr(&c->output); 770 ucp = (u_char *) buffer_ptr(b);
458 if (ucp[0] == 0x42) { /* Byte order MSB first. */ 771 if (ucp[0] == 0x42) { /* Byte order MSB first. */
459 proto_len = 256 * ucp[6] + ucp[7]; 772 proto_len = 256 * ucp[6] + ucp[7];
460 data_len = 256 * ucp[8] + ucp[9]; 773 data_len = 256 * ucp[8] + ucp[9];
@@ -468,7 +781,7 @@ x11_open_helper(Channel *c)
468 } 781 }
469 782
470 /* Check if the whole packet is in buffer. */ 783 /* Check if the whole packet is in buffer. */
471 if (buffer_len(&c->output) < 784 if (buffer_len(b) <
472 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3)) 785 12 + ((proto_len + 3) & ~3) + ((data_len + 3) & ~3))
473 return 0; 786 return 0;
474 787
@@ -504,7 +817,7 @@ x11_open_helper(Channel *c)
504void 817void
505channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) 818channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
506{ 819{
507 int ret = x11_open_helper(c); 820 int ret = x11_open_helper(&c->output);
508 if (ret == 1) { 821 if (ret == 1) {
509 /* Start normal processing for the channel. */ 822 /* Start normal processing for the channel. */
510 c->type = SSH_CHANNEL_OPEN; 823 c->type = SSH_CHANNEL_OPEN;
@@ -529,7 +842,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
529void 842void
530channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) 843channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
531{ 844{
532 int ret = x11_open_helper(c); 845 int ret = x11_open_helper(&c->output);
533 if (ret == 1) { 846 if (ret == 1) {
534 c->type = SSH_CHANNEL_OPEN; 847 c->type = SSH_CHANNEL_OPEN;
535 if (compat20) 848 if (compat20)
@@ -704,7 +1017,8 @@ channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
704 } else { 1017 } else {
705 packet_start(SSH_SMSG_X11_OPEN); 1018 packet_start(SSH_SMSG_X11_OPEN);
706 packet_put_int(nc->self); 1019 packet_put_int(nc->self);
707 if (have_hostname_in_open) 1020 if (packet_get_protocol_flags() &
1021 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
708 packet_put_string(buf, strlen(buf)); 1022 packet_put_string(buf, strlen(buf));
709 packet_send(); 1023 packet_send();
710 } 1024 }
@@ -755,7 +1069,8 @@ port_open_helper(Channel *c, char *rtype)
755 packet_put_int(c->self); 1069 packet_put_int(c->self);
756 packet_put_cstring(c->path); 1070 packet_put_cstring(c->path);
757 packet_put_int(c->host_port); 1071 packet_put_int(c->host_port);
758 if (have_hostname_in_open) 1072 if (packet_get_protocol_flags() &
1073 SSH_PROTOFLAG_HOST_IN_FWD_OPEN)
759 packet_put_cstring(c->remote_name); 1074 packet_put_cstring(c->remote_name);
760 packet_send(); 1075 packet_send();
761 } 1076 }
@@ -817,6 +1132,7 @@ void
817channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) 1132channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
818{ 1133{
819 Channel *nc; 1134 Channel *nc;
1135 char *name;
820 int newsock; 1136 int newsock;
821 struct sockaddr addr; 1137 struct sockaddr addr;
822 socklen_t addrlen; 1138 socklen_t addrlen;
@@ -828,12 +1144,14 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
828 error("accept from auth socket: %.100s", strerror(errno)); 1144 error("accept from auth socket: %.100s", strerror(errno));
829 return; 1145 return;
830 } 1146 }
1147 name = xstrdup("accepted auth socket");
831 nc = channel_new("accepted auth socket", 1148 nc = channel_new("accepted auth socket",
832 SSH_CHANNEL_OPENING, newsock, newsock, -1, 1149 SSH_CHANNEL_OPENING, newsock, newsock, -1,
833 c->local_window_max, c->local_maxpacket, 1150 c->local_window_max, c->local_maxpacket,
834 0, xstrdup("accepted auth socket"), 1); 1151 0, name, 1);
835 if (nc == NULL) { 1152 if (nc == NULL) {
836 error("channel_post_auth_listener: channel_new failed"); 1153 error("channel_post_auth_listener: channel_new failed");
1154 xfree(name);
837 close(newsock); 1155 close(newsock);
838 } 1156 }
839 if (compat20) { 1157 if (compat20) {
@@ -918,7 +1236,7 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
918 } else if (compat13) { 1236 } else if (compat13) {
919 buffer_consume(&c->output, buffer_len(&c->output)); 1237 buffer_consume(&c->output, buffer_len(&c->output));
920 c->type = SSH_CHANNEL_INPUT_DRAINING; 1238 c->type = SSH_CHANNEL_INPUT_DRAINING;
921 debug("channel %d: status set to input draining.", c->self); 1239 debug("channel %d: input draining.", c->self);
922 } else { 1240 } else {
923 chan_read_failed(c); 1241 chan_read_failed(c);
924 } 1242 }
@@ -956,7 +1274,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
956 return -1; 1274 return -1;
957 } else if (compat13) { 1275 } else if (compat13) {
958 buffer_consume(&c->output, buffer_len(&c->output)); 1276 buffer_consume(&c->output, buffer_len(&c->output));
959 debug("channel %d: status set to input draining.", c->self); 1277 debug("channel %d: input draining.", c->self);
960 c->type = SSH_CHANNEL_INPUT_DRAINING; 1278 c->type = SSH_CHANNEL_INPUT_DRAINING;
961 } else { 1279 } else {
962 chan_write_failed(c); 1280 chan_write_failed(c);
@@ -1196,6 +1514,10 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
1196 } 1514 }
1197} 1515}
1198 1516
1517/*
1518 * Allocate/update select bitmasks and add any bits relevant to channels in
1519 * select bitmasks.
1520 */
1199void 1521void
1200channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 1522channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
1201 int rekeying) 1523 int rekeying)
@@ -1222,12 +1544,17 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
1222 channel_handler(channel_pre, *readsetp, *writesetp); 1544 channel_handler(channel_pre, *readsetp, *writesetp);
1223} 1545}
1224 1546
1547/*
1548 * After select, perform any appropriate operations for channels which have
1549 * events pending.
1550 */
1225void 1551void
1226channel_after_select(fd_set * readset, fd_set * writeset) 1552channel_after_select(fd_set * readset, fd_set * writeset)
1227{ 1553{
1228 channel_handler(channel_post, readset, writeset); 1554 channel_handler(channel_post, readset, writeset);
1229} 1555}
1230 1556
1557
1231/* If there is data to send to the connection, enqueue some of it now. */ 1558/* If there is data to send to the connection, enqueue some of it now. */
1232 1559
1233void 1560void
@@ -1237,12 +1564,14 @@ channel_output_poll()
1237 Channel *c; 1564 Channel *c;
1238 1565
1239 for (i = 0; i < channels_alloc; i++) { 1566 for (i = 0; i < channels_alloc; i++) {
1240
1241 c = channels[i]; 1567 c = channels[i];
1242 if (c == NULL) 1568 if (c == NULL)
1243 continue; 1569 continue;
1244 1570
1245 /* We are only interested in channels that can have buffered incoming data. */ 1571 /*
1572 * We are only interested in channels that can have buffered
1573 * incoming data.
1574 */
1246 if (compat13) { 1575 if (compat13) {
1247 if (c->type != SSH_CHANNEL_OPEN && 1576 if (c->type != SSH_CHANNEL_OPEN &&
1248 c->type != SSH_CHANNEL_INPUT_DRAINING) 1577 c->type != SSH_CHANNEL_INPUT_DRAINING)
@@ -1262,7 +1591,10 @@ channel_output_poll()
1262 if ((c->istate == CHAN_INPUT_OPEN || 1591 if ((c->istate == CHAN_INPUT_OPEN ||
1263 c->istate == CHAN_INPUT_WAIT_DRAIN) && 1592 c->istate == CHAN_INPUT_WAIT_DRAIN) &&
1264 (len = buffer_len(&c->input)) > 0) { 1593 (len = buffer_len(&c->input)) > 0) {
1265 /* Send some data for the other side over the secure connection. */ 1594 /*
1595 * Send some data for the other side over the secure
1596 * connection.
1597 */
1266 if (compat20) { 1598 if (compat20) {
1267 if (len > c->remote_window) 1599 if (len > c->remote_window)
1268 len = c->remote_window; 1600 len = c->remote_window;
@@ -1320,11 +1652,8 @@ channel_output_poll()
1320 } 1652 }
1321} 1653}
1322 1654
1323/* 1655
1324 * This is called when a packet of type CHANNEL_DATA has just been received. 1656/* -- protocol input */
1325 * The message type has already been consumed, but channel number and data is
1326 * still there.
1327 */
1328 1657
1329void 1658void
1330channel_input_data(int type, int plen, void *ctxt) 1659channel_input_data(int type, int plen, void *ctxt)
@@ -1371,6 +1700,7 @@ channel_input_data(int type, int plen, void *ctxt)
1371 buffer_append(&c->output, data, data_len); 1700 buffer_append(&c->output, data, data_len);
1372 xfree(data); 1701 xfree(data);
1373} 1702}
1703
1374void 1704void
1375channel_input_extended_data(int type, int plen, void *ctxt) 1705channel_input_extended_data(int type, int plen, void *ctxt)
1376{ 1706{
@@ -1411,36 +1741,6 @@ channel_input_extended_data(int type, int plen, void *ctxt)
1411 xfree(data); 1741 xfree(data);
1412} 1742}
1413 1743
1414
1415/*
1416 * Returns true if no channel has too much buffered data, and false if one or
1417 * more channel is overfull.
1418 */
1419
1420int
1421channel_not_very_much_buffered_data()
1422{
1423 u_int i;
1424 Channel *c;
1425
1426 for (i = 0; i < channels_alloc; i++) {
1427 c = channels[i];
1428 if (c != NULL && c->type == SSH_CHANNEL_OPEN) {
1429 if (!compat20 && buffer_len(&c->input) > packet_get_maxsize()) {
1430 debug("channel %d: big input buffer %d",
1431 c->self, buffer_len(&c->input));
1432 return 0;
1433 }
1434 if (buffer_len(&c->output) > packet_get_maxsize()) {
1435 debug("channel %d: big output buffer %d",
1436 c->self, buffer_len(&c->output));
1437 return 0;
1438 }
1439 }
1440 }
1441 return 1;
1442}
1443
1444void 1744void
1445channel_input_ieof(int type, int plen, void *ctxt) 1745channel_input_ieof(int type, int plen, void *ctxt)
1446{ 1746{
@@ -1655,193 +1955,46 @@ channel_input_window_adjust(int type, int plen, void *ctxt)
1655 c->remote_window += adjust; 1955 c->remote_window += adjust;
1656} 1956}
1657 1957
1658/*
1659 * Stops listening for channels, and removes any unix domain sockets that we
1660 * might have.
1661 */
1662
1663void
1664channel_stop_listening()
1665{
1666 int i;
1667 Channel *c;
1668
1669 for (i = 0; i < channels_alloc; i++) {
1670 c = channels[i];
1671 if (c != NULL) {
1672 switch (c->type) {
1673 case SSH_CHANNEL_AUTH_SOCKET:
1674 close(c->sock);
1675 unlink(c->path);
1676 channel_free(c);
1677 break;
1678 case SSH_CHANNEL_PORT_LISTENER:
1679 case SSH_CHANNEL_RPORT_LISTENER:
1680 case SSH_CHANNEL_X11_LISTENER:
1681 close(c->sock);
1682 channel_free(c);
1683 break;
1684 default:
1685 break;
1686 }
1687 }
1688 }
1689}
1690
1691/*
1692 * Closes the sockets/fds of all channels. This is used to close extra file
1693 * descriptors after a fork.
1694 */
1695
1696void 1958void
1697channel_close_all() 1959channel_input_port_open(int type, int plen, void *ctxt)
1698{ 1960{
1699 int i; 1961 Channel *c = NULL;
1700 1962 u_short host_port;
1701 for (i = 0; i < channels_alloc; i++) 1963 char *host, *originator_string;
1702 if (channels[i] != NULL) 1964 int remote_id, sock = -1;
1703 channel_close_fds(channels[i]);
1704}
1705
1706/* Returns true if any channel is still open. */
1707 1965
1708int 1966 remote_id = packet_get_int();
1709channel_still_open() 1967 host = packet_get_string(NULL);
1710{ 1968 host_port = packet_get_int();
1711 int i;
1712 Channel *c;
1713 1969
1714 for (i = 0; i < channels_alloc; i++) { 1970 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
1715 c = channels[i]; 1971 originator_string = packet_get_string(NULL);
1716 if (c == NULL) 1972 } else {
1717 continue; 1973 originator_string = xstrdup("unknown (remote did not supply name)");
1718 switch (c->type) {
1719 case SSH_CHANNEL_X11_LISTENER:
1720 case SSH_CHANNEL_PORT_LISTENER:
1721 case SSH_CHANNEL_RPORT_LISTENER:
1722 case SSH_CHANNEL_CLOSED:
1723 case SSH_CHANNEL_AUTH_SOCKET:
1724 case SSH_CHANNEL_DYNAMIC:
1725 case SSH_CHANNEL_CONNECTING:
1726 case SSH_CHANNEL_ZOMBIE:
1727 continue;
1728 case SSH_CHANNEL_LARVAL:
1729 if (!compat20)
1730 fatal("cannot happen: SSH_CHANNEL_LARVAL");
1731 continue;
1732 case SSH_CHANNEL_OPENING:
1733 case SSH_CHANNEL_OPEN:
1734 case SSH_CHANNEL_X11_OPEN:
1735 return 1;
1736 case SSH_CHANNEL_INPUT_DRAINING:
1737 case SSH_CHANNEL_OUTPUT_DRAINING:
1738 if (!compat13)
1739 fatal("cannot happen: OUT_DRAIN");
1740 return 1;
1741 default:
1742 fatal("channel_still_open: bad channel type %d", c->type);
1743 /* NOTREACHED */
1744 }
1745 } 1974 }
1746 return 0; 1975 packet_done();
1747} 1976 sock = channel_connect_to(host, host_port);
1748 1977 if (sock != -1) {
1749/* Returns the id of an open channel suitable for keepaliving */ 1978 c = channel_new("connected socket",
1750 1979 SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
1751int 1980 originator_string, 1);
1752channel_find_open() 1981 if (c == NULL) {
1753{ 1982 error("channel_input_port_open: channel_new failed");
1754 int i; 1983 close(sock);
1755 Channel *c; 1984 } else {
1756 1985 c->remote_id = remote_id;
1757 for (i = 0; i < channels_alloc; i++) {
1758 c = channels[i];
1759 if (c == NULL)
1760 continue;
1761 switch (c->type) {
1762 case SSH_CHANNEL_CLOSED:
1763 case SSH_CHANNEL_DYNAMIC:
1764 case SSH_CHANNEL_X11_LISTENER:
1765 case SSH_CHANNEL_PORT_LISTENER:
1766 case SSH_CHANNEL_RPORT_LISTENER:
1767 case SSH_CHANNEL_OPENING:
1768 case SSH_CHANNEL_CONNECTING:
1769 case SSH_CHANNEL_ZOMBIE:
1770 continue;
1771 case SSH_CHANNEL_LARVAL:
1772 case SSH_CHANNEL_AUTH_SOCKET:
1773 case SSH_CHANNEL_OPEN:
1774 case SSH_CHANNEL_X11_OPEN:
1775 return i;
1776 case SSH_CHANNEL_INPUT_DRAINING:
1777 case SSH_CHANNEL_OUTPUT_DRAINING:
1778 if (!compat13)
1779 fatal("cannot happen: OUT_DRAIN");
1780 return i;
1781 default:
1782 fatal("channel_find_open: bad channel type %d", c->type);
1783 /* NOTREACHED */
1784 } 1986 }
1785 } 1987 }
1786 return -1; 1988 if (c == NULL) {
1989 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
1990 packet_put_int(remote_id);
1991 packet_send();
1992 }
1993 xfree(host);
1787} 1994}
1788 1995
1789 1996
1790/* 1997/* -- tcp forwarding */
1791 * Returns a message describing the currently open forwarded connections,
1792 * suitable for sending to the client. The message contains crlf pairs for
1793 * newlines.
1794 */
1795
1796char *
1797channel_open_message()
1798{
1799 Buffer buffer;
1800 Channel *c;
1801 char buf[1024], *cp;
1802 int i;
1803
1804 buffer_init(&buffer);
1805 snprintf(buf, sizeof buf, "The following connections are open:\r\n");
1806 buffer_append(&buffer, buf, strlen(buf));
1807 for (i = 0; i < channels_alloc; i++) {
1808 c = channels[i];
1809 if (c == NULL)
1810 continue;
1811 switch (c->type) {
1812 case SSH_CHANNEL_X11_LISTENER:
1813 case SSH_CHANNEL_PORT_LISTENER:
1814 case SSH_CHANNEL_RPORT_LISTENER:
1815 case SSH_CHANNEL_CLOSED:
1816 case SSH_CHANNEL_AUTH_SOCKET:
1817 case SSH_CHANNEL_ZOMBIE:
1818 continue;
1819 case SSH_CHANNEL_LARVAL:
1820 case SSH_CHANNEL_OPENING:
1821 case SSH_CHANNEL_CONNECTING:
1822 case SSH_CHANNEL_DYNAMIC:
1823 case SSH_CHANNEL_OPEN:
1824 case SSH_CHANNEL_X11_OPEN:
1825 case SSH_CHANNEL_INPUT_DRAINING:
1826 case SSH_CHANNEL_OUTPUT_DRAINING:
1827 snprintf(buf, sizeof buf, " #%d %.300s (t%d r%d i%d/%d o%d/%d fd %d/%d)\r\n",
1828 c->self, c->remote_name,
1829 c->type, c->remote_id,
1830 c->istate, buffer_len(&c->input),
1831 c->ostate, buffer_len(&c->output),
1832 c->rfd, c->wfd);
1833 buffer_append(&buffer, buf, strlen(buf));
1834 continue;
1835 default:
1836 fatal("channel_open_message: bad channel type %d", c->type);
1837 /* NOTREACHED */
1838 }
1839 }
1840 buffer_append(&buffer, "\0", 1);
1841 cp = xstrdup(buffer_ptr(&buffer));
1842 buffer_free(&buffer);
1843 return cp;
1844}
1845 1998
1846/* 1999/*
1847 * Initiate forwarding of connections to local port "port" through the secure 2000 * Initiate forwarding of connections to local port "port" through the secure
@@ -1868,7 +2021,7 @@ channel_request_forwarding(
1868 int gateway_ports, int remote_fwd) 2021 int gateway_ports, int remote_fwd)
1869{ 2022{
1870 Channel *c; 2023 Channel *c;
1871 int success, sock, on = 1, ctype; 2024 int success, sock, on = 1, type;
1872 struct addrinfo hints, *ai, *aitop; 2025 struct addrinfo hints, *ai, *aitop;
1873 char ntop[NI_MAXHOST], strport[NI_MAXSERV]; 2026 char ntop[NI_MAXHOST], strport[NI_MAXSERV];
1874 const char *host; 2027 const char *host;
@@ -1878,10 +2031,10 @@ channel_request_forwarding(
1878 2031
1879 if (remote_fwd) { 2032 if (remote_fwd) {
1880 host = listen_address; 2033 host = listen_address;
1881 ctype = SSH_CHANNEL_RPORT_LISTENER; 2034 type = SSH_CHANNEL_RPORT_LISTENER;
1882 } else { 2035 } else {
1883 host = host_to_connect; 2036 host = host_to_connect;
1884 ctype =SSH_CHANNEL_PORT_LISTENER; 2037 type = SSH_CHANNEL_PORT_LISTENER;
1885 } 2038 }
1886 2039
1887 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { 2040 if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) {
@@ -1945,7 +2098,7 @@ channel_request_forwarding(
1945 continue; 2098 continue;
1946 } 2099 }
1947 /* Allocate a channel number for the socket. */ 2100 /* Allocate a channel number for the socket. */
1948 c = channel_new("port listener", ctype, sock, sock, -1, 2101 c = channel_new("port listener", type, sock, sock, -1,
1949 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 2102 CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
1950 0, xstrdup("port listener"), 1); 2103 0, xstrdup("port listener"), 1);
1951 if (c == NULL) { 2104 if (c == NULL) {
@@ -2183,58 +2336,13 @@ channel_connect_to(const char *host, u_short port)
2183 return connect_to(host, port); 2336 return connect_to(host, port);
2184} 2337}
2185 2338
2186/* 2339/* -- X11 forwarding */
2187 * This is called after receiving PORT_OPEN message. This attempts to
2188 * connect to the given host:port, and sends back CHANNEL_OPEN_CONFIRMATION
2189 * or CHANNEL_OPEN_FAILURE.
2190 */
2191
2192void
2193channel_input_port_open(int type, int plen, void *ctxt)
2194{
2195 Channel *c = NULL;
2196 u_short host_port;
2197 char *host, *originator_string;
2198 int remote_id, sock = -1;
2199
2200 remote_id = packet_get_int();
2201 host = packet_get_string(NULL);
2202 host_port = packet_get_int();
2203
2204 if (have_hostname_in_open) {
2205 originator_string = packet_get_string(NULL);
2206 } else {
2207 originator_string = xstrdup("unknown (remote did not supply name)");
2208 }
2209 packet_done();
2210 sock = channel_connect_to(host, host_port);
2211 if (sock != -1) {
2212 c = channel_new("connected socket",
2213 SSH_CHANNEL_CONNECTING, sock, sock, -1, 0, 0, 0,
2214 originator_string, 1);
2215 if (c == NULL) {
2216 error("channel_input_port_open: channel_new failed");
2217 close(sock);
2218 } else {
2219 c->remote_id = remote_id;
2220 }
2221 }
2222 if (c == NULL) {
2223 packet_start(SSH_MSG_CHANNEL_OPEN_FAILURE);
2224 packet_put_int(remote_id);
2225 packet_send();
2226 }
2227 xfree(host);
2228}
2229 2340
2230/* 2341/*
2231 * Creates an internet domain socket for listening for X11 connections. 2342 * Creates an internet domain socket for listening for X11 connections.
2232 * Returns a suitable value for the DISPLAY variable, or NULL if an error 2343 * Returns a suitable value for the DISPLAY variable, or NULL if an error
2233 * occurs. 2344 * occurs.
2234 */ 2345 */
2235
2236#define NUM_SOCKS 10
2237
2238char * 2346char *
2239x11_create_display_inet(int screen_number, int x11_display_offset) 2347x11_create_display_inet(int screen_number, int x11_display_offset)
2240{ 2348{
@@ -2515,7 +2623,8 @@ x11_input_open(int type, int plen, void *ctxt)
2515 debug("Received X11 open request."); 2623 debug("Received X11 open request.");
2516 2624
2517 remote_id = packet_get_int(); 2625 remote_id = packet_get_int();
2518 if (have_hostname_in_open) { 2626
2627 if (packet_get_protocol_flags() & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) {
2519 remote_host = packet_get_string(NULL); 2628 remote_host = packet_get_string(NULL);
2520 } else { 2629 } else {
2521 remote_host = xstrdup("unknown (remote did not supply name)"); 2630 remote_host = xstrdup("unknown (remote did not supply name)");
@@ -2574,8 +2683,8 @@ deny_input_open(int type, int plen, void *ctxt)
2574/* 2683/*
2575 * Requests forwarding of X11 connections, generates fake authentication 2684 * Requests forwarding of X11 connections, generates fake authentication
2576 * data, and enables authentication spoofing. 2685 * data, and enables authentication spoofing.
2686 * This should be called in the client only.
2577 */ 2687 */
2578
2579void 2688void
2580x11_request_forwarding_with_spoofing(int client_session_id, 2689x11_request_forwarding_with_spoofing(int client_session_id,
2581 const char *proto, const char *data) 2690 const char *proto, const char *data)
@@ -2640,6 +2749,9 @@ x11_request_forwarding_with_spoofing(int client_session_id,
2640 xfree(new_data); 2749 xfree(new_data);
2641} 2750}
2642 2751
2752
2753/* -- agent forwarding */
2754
2643/* Sends a message to the server to request authentication fd forwarding. */ 2755/* Sends a message to the server to request authentication fd forwarding. */
2644 2756
2645void 2757void
@@ -2659,7 +2771,7 @@ auth_request_forwarding()
2659char * 2771char *
2660auth_get_socket_name() 2772auth_get_socket_name()
2661{ 2773{
2662 return channel_forwarded_auth_socket_name; 2774 return auth_sock_name;
2663} 2775}
2664 2776
2665/* removes the agent forwarding socket */ 2777/* removes the agent forwarding socket */
@@ -2667,8 +2779,8 @@ auth_get_socket_name()
2667void 2779void
2668cleanup_socket(void) 2780cleanup_socket(void)
2669{ 2781{
2670 unlink(channel_forwarded_auth_socket_name); 2782 unlink(auth_sock_name);
2671 rmdir(channel_forwarded_auth_socket_dir); 2783 rmdir(auth_sock_dir);
2672} 2784}
2673 2785
2674/* 2786/*
@@ -2683,30 +2795,32 @@ auth_input_request_forwarding(struct passwd * pw)
2683 int sock; 2795 int sock;
2684 struct sockaddr_un sunaddr; 2796 struct sockaddr_un sunaddr;
2685 2797
2686 if (auth_get_socket_name() != NULL) 2798 if (auth_get_socket_name() != NULL) {
2687 fatal("Protocol error: authentication forwarding requested twice."); 2799 error("authentication forwarding requested twice.");
2800 return 0;
2801 }
2688 2802
2689 /* Temporarily drop privileged uid for mkdir/bind. */ 2803 /* Temporarily drop privileged uid for mkdir/bind. */
2690 temporarily_use_uid(pw); 2804 temporarily_use_uid(pw);
2691 2805
2692 /* Allocate a buffer for the socket name, and format the name. */ 2806 /* Allocate a buffer for the socket name, and format the name. */
2693 channel_forwarded_auth_socket_name = xmalloc(MAX_SOCKET_NAME); 2807 auth_sock_name = xmalloc(MAXPATHLEN);
2694 channel_forwarded_auth_socket_dir = xmalloc(MAX_SOCKET_NAME); 2808 auth_sock_dir = xmalloc(MAXPATHLEN);
2695 strlcpy(channel_forwarded_auth_socket_dir, "/tmp/ssh-XXXXXXXX", MAX_SOCKET_NAME); 2809 strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
2696 2810
2697 /* Create private directory for socket */ 2811 /* Create private directory for socket */
2698 if (mkdtemp(channel_forwarded_auth_socket_dir) == NULL) { 2812 if (mkdtemp(auth_sock_dir) == NULL) {
2699 packet_send_debug("Agent forwarding disabled: mkdtemp() failed: %.100s", 2813 packet_send_debug("Agent forwarding disabled: "
2700 strerror(errno)); 2814 "mkdtemp() failed: %.100s", strerror(errno));
2701 restore_uid(); 2815 restore_uid();
2702 xfree(channel_forwarded_auth_socket_name); 2816 xfree(auth_sock_name);
2703 xfree(channel_forwarded_auth_socket_dir); 2817 xfree(auth_sock_dir);
2704 channel_forwarded_auth_socket_name = NULL; 2818 auth_sock_name = NULL;
2705 channel_forwarded_auth_socket_dir = NULL; 2819 auth_sock_dir = NULL;
2706 return 0; 2820 return 0;
2707 } 2821 }
2708 snprintf(channel_forwarded_auth_socket_name, MAX_SOCKET_NAME, "%s/agent.%d", 2822 snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%d",
2709 channel_forwarded_auth_socket_dir, (int) getpid()); 2823 auth_sock_dir, (int) getpid());
2710 2824
2711 if (atexit(cleanup_socket) < 0) { 2825 if (atexit(cleanup_socket) < 0) {
2712 int saved = errno; 2826 int saved = errno;
@@ -2721,7 +2835,7 @@ auth_input_request_forwarding(struct passwd * pw)
2721 /* Bind it to the name. */ 2835 /* Bind it to the name. */
2722 memset(&sunaddr, 0, sizeof(sunaddr)); 2836 memset(&sunaddr, 0, sizeof(sunaddr));
2723 sunaddr.sun_family = AF_UNIX; 2837 sunaddr.sun_family = AF_UNIX;
2724 strncpy(sunaddr.sun_path, channel_forwarded_auth_socket_name, 2838 strncpy(sunaddr.sun_path, auth_sock_name,
2725 sizeof(sunaddr.sun_path)); 2839 sizeof(sunaddr.sun_path));
2726 2840
2727 if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) 2841 if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
@@ -2744,7 +2858,7 @@ auth_input_request_forwarding(struct passwd * pw)
2744 close(sock); 2858 close(sock);
2745 return 0; 2859 return 0;
2746 } 2860 }
2747 strlcpy(nc->path, channel_forwarded_auth_socket_name, sizeof(nc->path)); 2861 strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
2748 return 1; 2862 return 1;
2749} 2863}
2750 2864
@@ -2755,7 +2869,7 @@ auth_input_open_request(int type, int plen, void *ctxt)
2755{ 2869{
2756 Channel *c = NULL; 2870 Channel *c = NULL;
2757 int remote_id, sock; 2871 int remote_id, sock;
2758 char *dummyname; 2872 char *name;
2759 2873
2760 packet_integrity_check(plen, 4, type); 2874 packet_integrity_check(plen, 4, type);
2761 2875
@@ -2775,10 +2889,12 @@ auth_input_open_request(int type, int plen, void *ctxt)
2775 * agent. 2889 * agent.
2776 */ 2890 */
2777 if (sock >= 0) { 2891 if (sock >= 0) {
2778 dummyname = xstrdup("authentication agent connection"); 2892 name = xstrdup("authentication agent connection");
2779 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock, -1, 0, 0, 0, dummyname, 1); 2893 c = channel_new("", SSH_CHANNEL_OPEN, sock, sock,
2894 -1, 0, 0, 0, name, 1);
2780 if (c == NULL) { 2895 if (c == NULL) {
2781 error("auth_input_open_request: channel_new failed"); 2896 error("auth_input_open_request: channel_new failed");
2897 xfree(name);
2782 close(sock); 2898 close(sock);
2783 } else { 2899 } else {
2784 c->remote_id = remote_id; 2900 c->remote_id = remote_id;
@@ -2796,105 +2912,3 @@ auth_input_open_request(int type, int plen, void *ctxt)
2796 } 2912 }
2797 packet_send(); 2913 packet_send();
2798} 2914}
2799
2800void
2801channel_start_open(int id)
2802{
2803 Channel *c = channel_lookup(id);
2804 if (c == NULL) {
2805 log("channel_open: %d: bad id", id);
2806 return;
2807 }
2808 debug("send channel open %d", id);
2809 packet_start(SSH2_MSG_CHANNEL_OPEN);
2810 packet_put_cstring(c->ctype);
2811 packet_put_int(c->self);
2812 packet_put_int(c->local_window);
2813 packet_put_int(c->local_maxpacket);
2814}
2815void
2816channel_open(int id)
2817{
2818 /* XXX REMOVE ME */
2819 channel_start_open(id);
2820 packet_send();
2821}
2822void
2823channel_request(int id, char *service, int wantconfirm)
2824{
2825 channel_request_start(id, service, wantconfirm);
2826 packet_send();
2827 debug("channel request %d: %s", id, service) ;
2828}
2829void
2830channel_request_start(int id, char *service, int wantconfirm)
2831{
2832 Channel *c = channel_lookup(id);
2833 if (c == NULL) {
2834 log("channel_request: %d: bad id", id);
2835 return;
2836 }
2837 packet_start(SSH2_MSG_CHANNEL_REQUEST);
2838 packet_put_int(c->remote_id);
2839 packet_put_cstring(service);
2840 packet_put_char(wantconfirm);
2841}
2842void
2843channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg)
2844{
2845 Channel *c = channel_lookup(id);
2846 if (c == NULL) {
2847 log("channel_register_callback: %d: bad id", id);
2848 return;
2849 }
2850 c->cb_event = mtype;
2851 c->cb_fn = fn;
2852 c->cb_arg = arg;
2853}
2854void
2855channel_register_cleanup(int id, channel_callback_fn *fn)
2856{
2857 Channel *c = channel_lookup(id);
2858 if (c == NULL) {
2859 log("channel_register_cleanup: %d: bad id", id);
2860 return;
2861 }
2862 c->dettach_user = fn;
2863}
2864void
2865channel_cancel_cleanup(int id)
2866{
2867 Channel *c = channel_lookup(id);
2868 if (c == NULL) {
2869 log("channel_cancel_cleanup: %d: bad id", id);
2870 return;
2871 }
2872 c->dettach_user = NULL;
2873}
2874void
2875channel_register_filter(int id, channel_filter_fn *fn)
2876{
2877 Channel *c = channel_lookup(id);
2878 if (c == NULL) {
2879 log("channel_register_filter: %d: bad id", id);
2880 return;
2881 }
2882 c->input_filter = fn;
2883}
2884
2885void
2886channel_set_fds(int id, int rfd, int wfd, int efd,
2887 int extusage, int nonblock)
2888{
2889 Channel *c = channel_lookup(id);
2890 if (c == NULL || c->type != SSH_CHANNEL_LARVAL)
2891 fatal("channel_activate for non-larval channel %d.", id);
2892 channel_register_fds(c, rfd, wfd, efd, extusage, nonblock);
2893 c->type = SSH_CHANNEL_OPEN;
2894 /* XXX window size? */
2895 c->local_window = c->local_window_max = c->local_maxpacket * 2;
2896 packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
2897 packet_put_int(c->remote_id);
2898 packet_put_int(c->local_window);
2899 packet_send();
2900}
diff --git a/channels.h b/channels.h
index 55d31854e..e9d583656 100644
--- a/channels.h
+++ b/channels.h
@@ -32,10 +32,10 @@
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.33 2001/05/28 23:14:49 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.35 2001/05/31 10:30:15 markus Exp $"); */
36 36
37#ifndef CHANNELS_H 37#ifndef CHANNEL_H
38#define CHANNELS_H 38#define CHANNEL_H
39 39
40#include "buffer.h" 40#include "buffer.h"
41 41
@@ -124,21 +124,42 @@ struct Channel {
124#define CHAN_X11_WINDOW_DEFAULT (4*1024) 124#define CHAN_X11_WINDOW_DEFAULT (4*1024)
125#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) 125#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2)
126 126
127/* possible input states */
128#define CHAN_INPUT_OPEN 0x01
129#define CHAN_INPUT_WAIT_DRAIN 0x02
130#define CHAN_INPUT_WAIT_OCLOSE 0x04
131#define CHAN_INPUT_CLOSED 0x08
127 132
128void channel_open(int id); 133/* possible output states */
134#define CHAN_OUTPUT_OPEN 0x10
135#define CHAN_OUTPUT_WAIT_DRAIN 0x20
136#define CHAN_OUTPUT_WAIT_IEOF 0x40
137#define CHAN_OUTPUT_CLOSED 0x80
138
139#define CHAN_CLOSE_SENT 0x01
140#define CHAN_CLOSE_RCVD 0x02
141
142
143/* channel management */
144
145Channel *channel_lookup(int id);
146Channel *
147channel_new(char *ctype, int type, int rfd, int wfd, int efd,
148 int window, int maxpack, int extusage, char *remote_name, int nonblock);
149void
150channel_set_fds(int id, int rfd, int wfd, int efd,
151 int extusage, int nonblock);
152void channel_free(Channel *c);
153
154void channel_send_open(int id);
129void channel_request(int id, char *service, int wantconfirm); 155void channel_request(int id, char *service, int wantconfirm);
130void channel_request_start(int id, char *service, int wantconfirm); 156void channel_request_start(int id, char *service, int wantconfirm);
131void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); 157void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg);
132void channel_register_cleanup(int id, channel_callback_fn *fn); 158void channel_register_cleanup(int id, channel_callback_fn *fn);
133void channel_register_filter(int id, channel_filter_fn *fn); 159void channel_register_filter(int id, channel_filter_fn *fn);
134void channel_cancel_cleanup(int id); 160void channel_cancel_cleanup(int id);
135Channel *channel_lookup(int id);
136 161
137void 162/* protocol handler */
138channel_set_fds(int id, int rfd, int wfd, int efd,
139 int extusage, int nonblock);
140
141void deny_input_open(int type, int plen, void *ctxt);
142 163
143void channel_input_channel_request(int type, int plen, void *ctxt); 164void channel_input_channel_request(int type, int plen, void *ctxt);
144void channel_input_close(int type, int plen, void *ctxt); 165void channel_input_close(int type, int plen, void *ctxt);
@@ -152,66 +173,22 @@ void channel_input_open_failure(int type, int plen, void *ctxt);
152void channel_input_port_open(int type, int plen, void *ctxt); 173void channel_input_port_open(int type, int plen, void *ctxt);
153void channel_input_window_adjust(int type, int plen, void *ctxt); 174void channel_input_window_adjust(int type, int plen, void *ctxt);
154 175
155/* Sets specific protocol options. */ 176/* file descriptor handling (read/write) */
156void channel_set_options(int hostname_in_open);
157
158/*
159 * Allocate a new channel object and set its type and socket. Remote_name
160 * must have been allocated with xmalloc; this will free it when the channel
161 * is freed.
162 */
163Channel *
164channel_new(char *ctype, int type, int rfd, int wfd, int efd,
165 int window, int maxpack, int extended_usage, char *remote_name,
166 int nonblock);
167
168/* Free the channel and close its socket. */
169void channel_free(Channel *c);
170 177
171/*
172 * Allocate/update select bitmasks and add any bits relevant to channels in
173 * select bitmasks.
174 */
175void 178void
176channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, 179channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
177 int rekeying); 180 int rekeying);
178
179/*
180 * After select, perform any appropriate operations for channels which have
181 * events pending.
182 */
183void channel_after_select(fd_set * readset, fd_set * writeset); 181void channel_after_select(fd_set * readset, fd_set * writeset);
184
185/* If there is data to send to the connection, send some of it now. */
186void channel_output_poll(void); 182void channel_output_poll(void);
187 183
188/* Returns true if no channel has too much buffered data. */
189int channel_not_very_much_buffered_data(void); 184int channel_not_very_much_buffered_data(void);
190
191/* This closes any sockets that are listening for connections; this removes
192 any unix domain sockets. */
193void channel_stop_listening(void); 185void channel_stop_listening(void);
194
195/*
196 * Closes the sockets of all channels. This is used to close extra file
197 * descriptors after a fork.
198 */
199void channel_close_all(void); 186void channel_close_all(void);
200
201/* Returns true if there is still an open channel over the connection. */
202int channel_still_open(void); 187int channel_still_open(void);
203
204/*
205 * Returns a string containing a list of all open channels. The list is
206 * suitable for displaying to the user. It uses crlf instead of newlines.
207 * The caller should free the string with xfree.
208 */
209char *channel_open_message(void); 188char *channel_open_message(void);
189int channel_find_open(void);
210 190
211/* 191/* channel_tcpfwd.c */
212 * Initiate forwarding of connections to local port "port" through the secure
213 * channel to host:port from remote side.
214 */
215int 192int
216channel_request_local_forwarding(u_short listen_port, 193channel_request_local_forwarding(u_short listen_port,
217 const char *host_to_connect, u_short port_to_connect, int gateway_ports); 194 const char *host_to_connect, u_short port_to_connect, int gateway_ports);
@@ -219,95 +196,53 @@ int
219channel_request_forwarding(const char *listen_address, u_short listen_port, 196channel_request_forwarding(const char *listen_address, u_short listen_port,
220 const char *host_to_connect, u_short port_to_connect, int gateway_ports, 197 const char *host_to_connect, u_short port_to_connect, int gateway_ports,
221 int remote_fwd); 198 int remote_fwd);
222
223/*
224 * Initiate forwarding of connections to port "port" on remote host through
225 * the secure channel to host:port from local side. This never returns if
226 * there was an error. This registers that open requests for that port are
227 * permitted.
228 */
229void 199void
230channel_request_remote_forwarding(u_short port, const char *host, 200channel_request_remote_forwarding(u_short port, const char *host,
231 u_short remote_port); 201 u_short remote_port);
232
233/*
234 * Permits opening to any host/port if permitted_opens[] is empty. This is
235 * usually called by the server, because the user could connect to any port
236 * anyway, and the server has no way to know but to trust the client anyway.
237 */
238void channel_permit_all_opens(void); 202void channel_permit_all_opens(void);
239
240/* Add host/port to list of allowed targets for port forwarding */
241void channel_add_permitted_opens(char *host, int port); 203void channel_add_permitted_opens(char *host, int port);
242
243/* Flush list */
244void channel_clear_permitted_opens(void); 204void channel_clear_permitted_opens(void);
245
246/*
247 * This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
248 * listening for the port, and sends back a success reply (or disconnect
249 * message if there was an error). This never returns if there was an error.
250 */
251void channel_input_port_forward_request(int is_root, int gateway_ports); 205void channel_input_port_forward_request(int is_root, int gateway_ports);
206int channel_connect_to(const char *host, u_short host_port);
207int channel_connect_by_listen_adress(u_short listen_port);
252 208
253/* 209/* x11 forwarding */
254 * Creates a port for X11 connections, and starts listening for it. Returns
255 * the display name, or NULL if an error was encountered.
256 */
257char *x11_create_display(int screen);
258 210
259/* 211int x11_connect_display(void);
260 * Creates an internet domain socket for listening for X11 connections. 212//int x11_check_cookie(Buffer *b);
261 * Returns a suitable value for the DISPLAY variable, or NULL if an error 213char *x11_create_display(int screen);
262 * occurs.
263 */
264char *x11_create_display_inet(int screen, int x11_display_offset); 214char *x11_create_display_inet(int screen, int x11_display_offset);
265
266/*
267 * This is called when SSH_SMSG_X11_OPEN is received. The packet contains
268 * the remote channel number. We should do whatever we want, and respond
269 * with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
270 */
271void x11_input_open(int type, int plen, void *ctxt); 215void x11_input_open(int type, int plen, void *ctxt);
272
273/*
274 * Requests forwarding of X11 connections. This should be called on the
275 * client only.
276 */
277void x11_request_forwarding(void); 216void x11_request_forwarding(void);
278
279/*
280 * Requests forwarding for X11 connections, with authentication spoofing.
281 * This should be called in the client only.
282 */
283void 217void
284x11_request_forwarding_with_spoofing(int client_session_id, 218x11_request_forwarding_with_spoofing(int client_session_id,
285 const char *proto, const char *data); 219 const char *proto, const char *data);
220void deny_input_open(int type, int plen, void *ctxt);
286 221
287/* Sends a message to the server to request authentication fd forwarding. */ 222/* agent forwarding */
288void auth_request_forwarding(void);
289 223
290/* 224void auth_request_forwarding(void);
291 * Returns the name of the forwarded authentication socket. Returns NULL if
292 * there is no forwarded authentication socket. The returned value points to
293 * a static buffer.
294 */
295char *auth_get_socket_name(void); 225char *auth_get_socket_name(void);
296
297/*
298 * This is called to process SSH_CMSG_AGENT_REQUEST_FORWARDING on the server.
299 * This starts forwarding authentication requests.
300 */
301int auth_input_request_forwarding(struct passwd * pw); 226int auth_input_request_forwarding(struct passwd * pw);
302
303/* This is called to process an SSH_SMSG_AGENT_OPEN message. */
304void auth_input_open_request(int type, int plen, void *ctxt); 227void auth_input_open_request(int type, int plen, void *ctxt);
305 228
306/* XXX */ 229/* channel close */
307int channel_connect_to(const char *host, u_short host_port);
308int channel_connect_by_listen_adress(u_short listen_port);
309int x11_connect_display(void);
310 230
311int channel_find_open(void); 231typedef void chan_event_fn(Channel * c);
232
233/* for the input state */
234extern chan_event_fn *chan_rcvd_oclose;
235extern chan_event_fn *chan_read_failed;
236extern chan_event_fn *chan_ibuf_empty;
237
238/* for the output state */
239extern chan_event_fn *chan_rcvd_ieof;
240extern chan_event_fn *chan_write_failed;
241extern chan_event_fn *chan_obuf_empty;
242
243int chan_is_dead(Channel * c);
244void chan_mark_dead(Channel * c);
245void chan_init_iostates(Channel * c);
246void chan_init(void);
312 247
313#endif 248#endif