diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | channels.c | 896 | ||||
-rw-r--r-- | channels.h | 185 |
3 files changed, 518 insertions, 567 deletions
@@ -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 | ||
16 | 20010606 | 18 | 20010606 |
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" |
43 | RCSID("$OpenBSD: channels.c,v 1.119 2001/05/28 23:25:24 markus Exp $"); | 43 | RCSID("$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 | */ |
87 | static int channel_max_fd = 0; | 78 | static int channel_max_fd = 0; |
88 | 79 | ||
89 | /* Name and directory of socket for authentication agent forwarding. */ | ||
90 | static char *channel_forwarded_auth_socket_name = NULL; | ||
91 | static char *channel_forwarded_auth_socket_dir = NULL; | ||
92 | |||
93 | /* Saved X11 authentication protocol name. */ | ||
94 | char *x11_saved_proto = NULL; | ||
95 | |||
96 | /* Saved X11 authentication data. This is the real data. */ | ||
97 | char *x11_saved_data = NULL; | ||
98 | u_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 | */ | ||
104 | char *x11_fake_data = NULL; | ||
105 | u_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. */ |
120 | static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION]; | 96 | static 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. */ |
122 | static int num_permitted_opens = 0; | 99 | static int num_permitted_opens = 0; |
123 | /* | 100 | /* |
@@ -127,23 +104,43 @@ static int num_permitted_opens = 0; | |||
127 | */ | 104 | */ |
128 | static int all_opens_permitted = 0; | 105 | static int all_opens_permitted = 0; |
129 | 106 | ||
130 | /* This is set to true if both sides support SSH_PROTOFLAG_HOST_IN_FWD_OPEN. */ | ||
131 | static int have_hostname_in_open = 0; | ||
132 | 107 | ||
133 | /* AF_UNSPEC or AF_INET or AF_INET6 */ | 108 | /* -- X11 forwarding */ |
134 | extern int IPv4or6; | ||
135 | 109 | ||
136 | void 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. */ |
114 | static char *x11_saved_proto = NULL; | ||
139 | 115 | ||
140 | void | 116 | /* Saved X11 authentication data. This is the real data. */ |
141 | channel_set_options(int hostname_in_open) | 117 | static char *x11_saved_data = NULL; |
142 | { | 118 | static 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 | */ | ||
124 | static char *x11_fake_data = NULL; | ||
125 | static 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. */ | ||
133 | static char *auth_sock_name = NULL; | ||
134 | static char *auth_sock_dir = NULL; | ||
135 | |||
136 | |||
137 | /* AF_UNSPEC or AF_INET or AF_INET6 */ | ||
138 | extern int IPv4or6; | ||
139 | |||
140 | /* helper */ | ||
141 | void port_open_helper(Channel *c, char *rtype); | ||
142 | |||
143 | /* -- channel core */ | ||
147 | 144 | ||
148 | Channel * | 145 | Channel * |
149 | channel_lookup(int id) | 146 | channel_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 | |||
343 | void | ||
344 | channel_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 | |||
376 | void | ||
377 | channel_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 | |||
391 | int | ||
392 | channel_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 | |||
417 | int | ||
418 | channel_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 | |||
460 | int | ||
461 | channel_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 | |||
505 | char * | ||
506 | channel_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 | |||
555 | void | ||
556 | channel_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 | |||
572 | void | ||
573 | channel_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 | } | ||
579 | void | ||
580 | channel_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 | } | ||
592 | void | ||
593 | channel_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 | } | ||
604 | void | ||
605 | channel_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 | } | ||
614 | void | ||
615 | channel_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 | } | ||
624 | void | ||
625 | channel_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 | |||
635 | void | ||
636 | channel_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 | */ |
446 | int | 759 | int |
447 | x11_open_helper(Channel *c) | 760 | x11_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) | |||
504 | void | 817 | void |
505 | channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) | 818 | channel_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) | |||
529 | void | 842 | void |
530 | channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) | 843 | channel_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 | |||
817 | channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset) | 1132 | channel_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 | */ | ||
1199 | void | 1521 | void |
1200 | channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | 1522 | channel_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 | */ | ||
1225 | void | 1551 | void |
1226 | channel_after_select(fd_set * readset, fd_set * writeset) | 1552 | channel_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 | ||
1233 | void | 1560 | void |
@@ -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 | ||
1329 | void | 1658 | void |
1330 | channel_input_data(int type, int plen, void *ctxt) | 1659 | channel_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 | |||
1374 | void | 1704 | void |
1375 | channel_input_extended_data(int type, int plen, void *ctxt) | 1705 | channel_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 | |||
1420 | int | ||
1421 | channel_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 | |||
1444 | void | 1744 | void |
1445 | channel_input_ieof(int type, int plen, void *ctxt) | 1745 | channel_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 | |||
1663 | void | ||
1664 | channel_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 | |||
1696 | void | 1958 | void |
1697 | channel_close_all() | 1959 | channel_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 | ||
1708 | int | 1966 | remote_id = packet_get_int(); |
1709 | channel_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, | |
1751 | int | 1980 | originator_string, 1); |
1752 | channel_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 | |||
1796 | char * | ||
1797 | channel_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 | |||
2192 | void | ||
2193 | channel_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 | |||
2238 | char * | 2346 | char * |
2239 | x11_create_display_inet(int screen_number, int x11_display_offset) | 2347 | x11_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 | |||
2579 | void | 2688 | void |
2580 | x11_request_forwarding_with_spoofing(int client_session_id, | 2689 | x11_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 | ||
2645 | void | 2757 | void |
@@ -2659,7 +2771,7 @@ auth_request_forwarding() | |||
2659 | char * | 2771 | char * |
2660 | auth_get_socket_name() | 2772 | auth_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() | |||
2667 | void | 2779 | void |
2668 | cleanup_socket(void) | 2780 | cleanup_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 | |||
2800 | void | ||
2801 | channel_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 | } | ||
2815 | void | ||
2816 | channel_open(int id) | ||
2817 | { | ||
2818 | /* XXX REMOVE ME */ | ||
2819 | channel_start_open(id); | ||
2820 | packet_send(); | ||
2821 | } | ||
2822 | void | ||
2823 | channel_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 | } | ||
2829 | void | ||
2830 | channel_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 | } | ||
2842 | void | ||
2843 | channel_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 | } | ||
2854 | void | ||
2855 | channel_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 | } | ||
2864 | void | ||
2865 | channel_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 | } | ||
2874 | void | ||
2875 | channel_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 | |||
2885 | void | ||
2886 | channel_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 | ||
128 | void 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 | |||
145 | Channel *channel_lookup(int id); | ||
146 | Channel * | ||
147 | channel_new(char *ctype, int type, int rfd, int wfd, int efd, | ||
148 | int window, int maxpack, int extusage, char *remote_name, int nonblock); | ||
149 | void | ||
150 | channel_set_fds(int id, int rfd, int wfd, int efd, | ||
151 | int extusage, int nonblock); | ||
152 | void channel_free(Channel *c); | ||
153 | |||
154 | void channel_send_open(int id); | ||
129 | void channel_request(int id, char *service, int wantconfirm); | 155 | void channel_request(int id, char *service, int wantconfirm); |
130 | void channel_request_start(int id, char *service, int wantconfirm); | 156 | void channel_request_start(int id, char *service, int wantconfirm); |
131 | void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); | 157 | void channel_register_callback(int id, int mtype, channel_callback_fn *fn, void *arg); |
132 | void channel_register_cleanup(int id, channel_callback_fn *fn); | 158 | void channel_register_cleanup(int id, channel_callback_fn *fn); |
133 | void channel_register_filter(int id, channel_filter_fn *fn); | 159 | void channel_register_filter(int id, channel_filter_fn *fn); |
134 | void channel_cancel_cleanup(int id); | 160 | void channel_cancel_cleanup(int id); |
135 | Channel *channel_lookup(int id); | ||
136 | 161 | ||
137 | void | 162 | /* protocol handler */ |
138 | channel_set_fds(int id, int rfd, int wfd, int efd, | ||
139 | int extusage, int nonblock); | ||
140 | |||
141 | void deny_input_open(int type, int plen, void *ctxt); | ||
142 | 163 | ||
143 | void channel_input_channel_request(int type, int plen, void *ctxt); | 164 | void channel_input_channel_request(int type, int plen, void *ctxt); |
144 | void channel_input_close(int type, int plen, void *ctxt); | 165 | void channel_input_close(int type, int plen, void *ctxt); |
@@ -152,66 +173,22 @@ void channel_input_open_failure(int type, int plen, void *ctxt); | |||
152 | void channel_input_port_open(int type, int plen, void *ctxt); | 173 | void channel_input_port_open(int type, int plen, void *ctxt); |
153 | void channel_input_window_adjust(int type, int plen, void *ctxt); | 174 | void channel_input_window_adjust(int type, int plen, void *ctxt); |
154 | 175 | ||
155 | /* Sets specific protocol options. */ | 176 | /* file descriptor handling (read/write) */ |
156 | void 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 | */ | ||
163 | Channel * | ||
164 | channel_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. */ | ||
169 | void channel_free(Channel *c); | ||
170 | 177 | ||
171 | /* | ||
172 | * Allocate/update select bitmasks and add any bits relevant to channels in | ||
173 | * select bitmasks. | ||
174 | */ | ||
175 | void | 178 | void |
176 | channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, | 179 | channel_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 | */ | ||
183 | void channel_after_select(fd_set * readset, fd_set * writeset); | 181 | void 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. */ | ||
186 | void channel_output_poll(void); | 182 | void channel_output_poll(void); |
187 | 183 | ||
188 | /* Returns true if no channel has too much buffered data. */ | ||
189 | int channel_not_very_much_buffered_data(void); | 184 | int 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. */ | ||
193 | void channel_stop_listening(void); | 185 | void 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 | */ | ||
199 | void channel_close_all(void); | 186 | void channel_close_all(void); |
200 | |||
201 | /* Returns true if there is still an open channel over the connection. */ | ||
202 | int channel_still_open(void); | 187 | int 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 | */ | ||
209 | char *channel_open_message(void); | 188 | char *channel_open_message(void); |
189 | int 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 | */ | ||
215 | int | 192 | int |
216 | channel_request_local_forwarding(u_short listen_port, | 193 | channel_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 | |||
219 | channel_request_forwarding(const char *listen_address, u_short listen_port, | 196 | channel_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 | */ | ||
229 | void | 199 | void |
230 | channel_request_remote_forwarding(u_short port, const char *host, | 200 | channel_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 | */ | ||
238 | void channel_permit_all_opens(void); | 202 | void channel_permit_all_opens(void); |
239 | |||
240 | /* Add host/port to list of allowed targets for port forwarding */ | ||
241 | void channel_add_permitted_opens(char *host, int port); | 203 | void channel_add_permitted_opens(char *host, int port); |
242 | |||
243 | /* Flush list */ | ||
244 | void channel_clear_permitted_opens(void); | 204 | void 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 | */ | ||
251 | void channel_input_port_forward_request(int is_root, int gateway_ports); | 205 | void channel_input_port_forward_request(int is_root, int gateway_ports); |
206 | int channel_connect_to(const char *host, u_short host_port); | ||
207 | int 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 | */ | ||
257 | char *x11_create_display(int screen); | ||
258 | 210 | ||
259 | /* | 211 | int 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 | 213 | char *x11_create_display(int screen); |
262 | * occurs. | ||
263 | */ | ||
264 | char *x11_create_display_inet(int screen, int x11_display_offset); | 214 | char *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 | */ | ||
271 | void x11_input_open(int type, int plen, void *ctxt); | 215 | void 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 | */ | ||
277 | void x11_request_forwarding(void); | 216 | void 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 | */ | ||
283 | void | 217 | void |
284 | x11_request_forwarding_with_spoofing(int client_session_id, | 218 | x11_request_forwarding_with_spoofing(int client_session_id, |
285 | const char *proto, const char *data); | 219 | const char *proto, const char *data); |
220 | void 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 */ |
288 | void auth_request_forwarding(void); | ||
289 | 223 | ||
290 | /* | 224 | void 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 | */ | ||
295 | char *auth_get_socket_name(void); | 225 | char *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 | */ | ||
301 | int auth_input_request_forwarding(struct passwd * pw); | 226 | int auth_input_request_forwarding(struct passwd * pw); |
302 | |||
303 | /* This is called to process an SSH_SMSG_AGENT_OPEN message. */ | ||
304 | void auth_input_open_request(int type, int plen, void *ctxt); | 227 | void auth_input_open_request(int type, int plen, void *ctxt); |
305 | 228 | ||
306 | /* XXX */ | 229 | /* channel close */ |
307 | int channel_connect_to(const char *host, u_short host_port); | ||
308 | int channel_connect_by_listen_adress(u_short listen_port); | ||
309 | int x11_connect_display(void); | ||
310 | 230 | ||
311 | int channel_find_open(void); | 231 | typedef void chan_event_fn(Channel * c); |
232 | |||
233 | /* for the input state */ | ||
234 | extern chan_event_fn *chan_rcvd_oclose; | ||
235 | extern chan_event_fn *chan_read_failed; | ||
236 | extern chan_event_fn *chan_ibuf_empty; | ||
237 | |||
238 | /* for the output state */ | ||
239 | extern chan_event_fn *chan_rcvd_ieof; | ||
240 | extern chan_event_fn *chan_write_failed; | ||
241 | extern chan_event_fn *chan_obuf_empty; | ||
242 | |||
243 | int chan_is_dead(Channel * c); | ||
244 | void chan_mark_dead(Channel * c); | ||
245 | void chan_init_iostates(Channel * c); | ||
246 | void chan_init(void); | ||
312 | 247 | ||
313 | #endif | 248 | #endif |