diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | channels.c | 211 | ||||
-rw-r--r-- | ssh.c | 6 |
3 files changed, 40 insertions, 204 deletions
@@ -3,18 +3,23 @@ | |||
3 | and temporary commented out 'catman-do:' since it is broken. Patches | 3 | and temporary commented out 'catman-do:' since it is broken. Patches |
4 | for the first two by Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> | 4 | for the first two by Lutz Jaenicke <Lutz.Jaenicke@aet.TU-Cottbus.DE> |
5 | - OpenBSD CVS Sync | 5 | - OpenBSD CVS Sync |
6 | - deraadt@cvs.openbsd.org 2001/04/16 08:26:04 | 6 | - deraadt@cvs.openbsd.org 2001/04/16 08:26:04 |
7 | [key.c] | 7 | [key.c] |
8 | better safe than sorry in later mods; yongari@kt-is.co.kr | 8 | better safe than sorry in later mods; yongari@kt-is.co.kr |
9 | - markus@cvs.openbsd.org 2001/04/17 08:14:01 | 9 | - markus@cvs.openbsd.org 2001/04/17 08:14:01 |
10 | [sshconnect1.c] | 10 | [sshconnect1.c] |
11 | check for key!=NULL, thanks to costa | 11 | check for key!=NULL, thanks to costa |
12 | - markus@cvs.openbsd.org 2001/04/17 09:52:48 | 12 | - markus@cvs.openbsd.org 2001/04/17 09:52:48 |
13 | [clientloop.c] | 13 | [clientloop.c] |
14 | handle EINTR/EAGAIN on read; ok deraadt@ | 14 | handle EINTR/EAGAIN on read; ok deraadt@ |
15 | - markus@cvs.openbsd.org 2001/04/17 10:53:26 | 15 | - markus@cvs.openbsd.org 2001/04/17 10:53:26 |
16 | [key.c key.h readconf.c readconf.h ssh.1 sshconnect2.c] | 16 | [key.c key.h readconf.c readconf.h ssh.1 sshconnect2.c] |
17 | add HostKeyAlgorithms; based on patch from res@shore.net; ok provos@ | 17 | add HostKeyAlgorithms; based on patch from res@shore.net; ok provos@ |
18 | - markus@cvs.openbsd.org 2001/04/17 12:55:04 | ||
19 | [channels.c ssh.c] | ||
20 | undo socks5 and https support since they are not really used and | ||
21 | only bloat ssh. remove -D from usage(), since '-D' is experimental. | ||
22 | |||
18 | 23 | ||
19 | 20010416 | 24 | 20010416 |
20 | - OpenBSD CVS Sync | 25 | - OpenBSD CVS Sync |
@@ -5140,4 +5145,4 @@ | |||
5140 | - Wrote replacements for strlcpy and mkdtemp | 5145 | - Wrote replacements for strlcpy and mkdtemp |
5141 | - Released 1.0pre1 | 5146 | - Released 1.0pre1 |
5142 | 5147 | ||
5143 | $Id: ChangeLog,v 1.1134 2001/04/17 18:11:36 mouring Exp $ | 5148 | $Id: ChangeLog,v 1.1135 2001/04/17 18:14:34 mouring Exp $ |
diff --git a/channels.c b/channels.c index d86cb1f08..57890aec9 100644 --- a/channels.c +++ b/channels.c | |||
@@ -40,7 +40,7 @@ | |||
40 | */ | 40 | */ |
41 | 41 | ||
42 | #include "includes.h" | 42 | #include "includes.h" |
43 | RCSID("$OpenBSD: channels.c,v 1.108 2001/04/14 16:17:14 markus Exp $"); | 43 | RCSID("$OpenBSD: channels.c,v 1.109 2001/04/17 12:55:03 markus Exp $"); |
44 | 44 | ||
45 | #include <openssl/rsa.h> | 45 | #include <openssl/rsa.h> |
46 | #include <openssl/dsa.h> | 46 | #include <openssl/dsa.h> |
@@ -542,79 +542,12 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset) | |||
542 | } | 542 | } |
543 | } | 543 | } |
544 | 544 | ||
545 | |||
546 | int | ||
547 | channel_decode_helper(Channel *c, int start, int lookfor) | ||
548 | { | ||
549 | u_char *p; | ||
550 | int i, have; | ||
551 | |||
552 | p = buffer_ptr(&c->input); | ||
553 | have = buffer_len(&c->input); | ||
554 | debug2("channel %d: decode_helper: start %d have %d lookfor %d", | ||
555 | c->self, start, have, lookfor); | ||
556 | if (have < start) | ||
557 | return 0; | ||
558 | for (i = start; i < have; i++) { | ||
559 | if (p[i] == lookfor) { | ||
560 | debug2("channel %d: decode_helper: matched at %d", | ||
561 | c->self, i); | ||
562 | if (lookfor == '\0' || | ||
563 | (i+3 < have && | ||
564 | p[i+1] == '\n' && | ||
565 | p[i+2] == '\r' && | ||
566 | p[i+3] == '\n')) | ||
567 | return i; | ||
568 | } | ||
569 | if (i > 4096) { | ||
570 | /* the peer is probably sending garbage */ | ||
571 | debug("channel %d: decode_helper: too long", | ||
572 | c->self); | ||
573 | return -1; | ||
574 | } | ||
575 | } | ||
576 | return 0; /* need more */ | ||
577 | } | ||
578 | |||
579 | /* try to decode a http connect header */ | ||
580 | int | ||
581 | channel_decode_https(Channel *c, fd_set * readset, fd_set * writeset) | ||
582 | { | ||
583 | u_char *p, *host, *buf; | ||
584 | int port, ret; | ||
585 | char httpok[] = "HTTP/1.0 200\r\n\r\n"; | ||
586 | |||
587 | debug2("channel %d: decode https connect", c->self); | ||
588 | ret = channel_decode_helper(c, strlen("connect "), '\r'); | ||
589 | if (ret <= 0) | ||
590 | return ret; | ||
591 | p = buffer_ptr(&c->input); | ||
592 | buf = xmalloc(ret+1); | ||
593 | host = xmalloc(ret); | ||
594 | memcpy(buf, p, ret); | ||
595 | buf[ret] = '\0'; | ||
596 | if (sscanf(buf, "CONNECT %[^:]:%u HTTP/", host, &port) != 2) { | ||
597 | debug("channel %d: cannot parse http header", c->self); | ||
598 | return -1; | ||
599 | } | ||
600 | debug("channel %d: dynamic request: https host %s port %u", | ||
601 | c->self, host, port); | ||
602 | strlcpy(c->path, host, sizeof(c->path)); | ||
603 | c->host_port = port; | ||
604 | xfree(host); | ||
605 | xfree(buf); | ||
606 | buffer_consume(&c->input, ret+4); | ||
607 | buffer_append(&c->output, httpok, strlen(httpok)); | ||
608 | |||
609 | return 1; | ||
610 | } | ||
611 | |||
612 | /* try to decode a socks4 header */ | 545 | /* try to decode a socks4 header */ |
613 | int | 546 | int |
614 | channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) | 547 | channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) |
615 | { | 548 | { |
616 | u_char *p, *host; | 549 | u_char *p, *host; |
617 | int len, have, ret; | 550 | int len, have, i, found; |
618 | char username[256]; | 551 | char username[256]; |
619 | struct { | 552 | struct { |
620 | u_int8_t version; | 553 | u_int8_t version; |
@@ -624,16 +557,33 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) | |||
624 | } s4_req, s4_rsp; | 557 | } s4_req, s4_rsp; |
625 | 558 | ||
626 | debug2("channel %d: decode socks4", c->self); | 559 | debug2("channel %d: decode socks4", c->self); |
627 | ret = channel_decode_helper(c, sizeof(s4_req), '\0'); | 560 | |
628 | if (ret <= 0) | 561 | have = buffer_len(&c->input); |
629 | return ret; | 562 | len = sizeof(s4_req); |
563 | if (have < len) | ||
564 | return 0; | ||
565 | p = buffer_ptr(&c->input); | ||
566 | for (found = 0, i = len; i < have; i++) { | ||
567 | if (p[i] == '\0') { | ||
568 | found = 1; | ||
569 | break; | ||
570 | } | ||
571 | if (i > 1024) { | ||
572 | /* the peer is probably sending garbage */ | ||
573 | debug("channel %d: decode socks4: too long", | ||
574 | c->self); | ||
575 | return -1; | ||
576 | } | ||
577 | } | ||
578 | if (!found) | ||
579 | return 0; | ||
630 | buffer_get(&c->input, (char *)&s4_req.version, 1); | 580 | buffer_get(&c->input, (char *)&s4_req.version, 1); |
631 | buffer_get(&c->input, (char *)&s4_req.command, 1); | 581 | buffer_get(&c->input, (char *)&s4_req.command, 1); |
632 | buffer_get(&c->input, (char *)&s4_req.dest_port, 2); | 582 | buffer_get(&c->input, (char *)&s4_req.dest_port, 2); |
633 | buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); | 583 | buffer_get(&c->input, (char *)&s4_req.dest_addr, 4); |
584 | have = buffer_len(&c->input); | ||
634 | p = buffer_ptr(&c->input); | 585 | p = buffer_ptr(&c->input); |
635 | len = strlen(p); | 586 | len = strlen(p); |
636 | have = buffer_len(&c->input); | ||
637 | debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); | 587 | debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); |
638 | if (len > have) | 588 | if (len > have) |
639 | fatal("channel %d: decode socks4: len %d > have %d", | 589 | fatal("channel %d: decode socks4: len %d > have %d", |
@@ -662,115 +612,6 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset) | |||
662 | return 1; | 612 | return 1; |
663 | } | 613 | } |
664 | 614 | ||
665 | /* try to decode a socks5 header */ | ||
666 | #define SSH_SOCKS5_AUTHDONE 0x1000 | ||
667 | #define SSH_SOCKS5_NOAUTH 0x00 | ||
668 | #define SSH_SOCKS5_IPV4 0x01 | ||
669 | #define SSH_SOCKS5_DOMAIN 0x03 | ||
670 | #define SSH_SOCKS5_IPV6 0x04 | ||
671 | #define SSH_SOCKS5_CONNECT 0x01 | ||
672 | #define SSH_SOCKS5_SUCCESS 0x00 | ||
673 | |||
674 | int | ||
675 | channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset) | ||
676 | { | ||
677 | struct { | ||
678 | u_int8_t version; | ||
679 | u_int8_t command; | ||
680 | u_int8_t reserved; | ||
681 | u_int8_t atyp; | ||
682 | } s5_req, s5_rsp; | ||
683 | u_int16_t dest_port; | ||
684 | u_char *p, dest_addr[255+1]; | ||
685 | int i, have, found, nmethods, addrlen, af; | ||
686 | |||
687 | debug2("channel %d: decode socks5", c->self); | ||
688 | p = buffer_ptr(&c->input); | ||
689 | if (p[0] != 0x05) | ||
690 | return -1; | ||
691 | have = buffer_len(&c->input); | ||
692 | if (!(c->flags & SSH_SOCKS5_AUTHDONE)) { | ||
693 | /* format: ver | nmethods | methods */ | ||
694 | if (have < 2) | ||
695 | return 0; | ||
696 | nmethods = p[1]; | ||
697 | if (have < nmethods + 2) | ||
698 | return 0; | ||
699 | /* look for method: "NO AUTHENTICATION REQUIRED" */ | ||
700 | for (found = 0, i = 2 ; i < nmethods + 2; i++) { | ||
701 | if (p[i] == SSH_SOCKS5_NOAUTH ) { | ||
702 | found = 1; | ||
703 | break; | ||
704 | } | ||
705 | } | ||
706 | if (!found) { | ||
707 | debug("channel %d: method SSH_SOCKS5_NOAUTH not found", | ||
708 | c->self); | ||
709 | return -1; | ||
710 | } | ||
711 | buffer_consume(&c->input, nmethods + 2); | ||
712 | buffer_put_char(&c->output, 0x05); /* version */ | ||
713 | buffer_put_char(&c->output, SSH_SOCKS5_NOAUTH); /* method */ | ||
714 | FD_SET(c->sock, writeset); | ||
715 | c->flags |= SSH_SOCKS5_AUTHDONE; | ||
716 | debug2("channel %d: socks5 auth done", c->self); | ||
717 | return 0; /* need more */ | ||
718 | } | ||
719 | debug2("channel %d: socks5 post auth", c->self); | ||
720 | if (have < sizeof(s5_req)+1) | ||
721 | return 0; /* need more */ | ||
722 | memcpy((char *)&s5_req, p, sizeof(s5_req)); | ||
723 | if (s5_req.version != 0x05 || | ||
724 | s5_req.command != SSH_SOCKS5_CONNECT || | ||
725 | s5_req.reserved != 0x00) { | ||
726 | debug("channel %d: only socks5 connect supported", c->self); | ||
727 | return -1; | ||
728 | } | ||
729 | switch(s5_req.atyp){ | ||
730 | case SSH_SOCKS5_IPV4: | ||
731 | addrlen = 4; | ||
732 | af = AF_INET; | ||
733 | break; | ||
734 | case SSH_SOCKS5_DOMAIN: | ||
735 | addrlen = p[sizeof(s5_req)]; | ||
736 | af = -1; | ||
737 | break; | ||
738 | case SSH_SOCKS5_IPV6: | ||
739 | addrlen = 16; | ||
740 | af = AF_INET6; | ||
741 | break; | ||
742 | default: | ||
743 | debug("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp); | ||
744 | return -1; | ||
745 | } | ||
746 | if (have < 4 + addrlen + 2) | ||
747 | return 0; | ||
748 | buffer_consume(&c->input, sizeof(s5_req)); | ||
749 | buffer_get(&c->input, (char *)&dest_addr, addrlen); | ||
750 | buffer_get(&c->input, (char *)&dest_port, 2); | ||
751 | dest_addr[addrlen] = '\0'; | ||
752 | if (s5_req.atyp == SSH_SOCKS5_DOMAIN) | ||
753 | strlcpy(c->path, dest_addr, sizeof(c->path)); | ||
754 | else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) | ||
755 | return -1; | ||
756 | c->host_port = ntohs(dest_port); | ||
757 | |||
758 | debug("channel %d: dynamic request: socks5 host %s port %u command %u", | ||
759 | c->self, c->path, c->host_port, s5_req.command); | ||
760 | |||
761 | s5_rsp.version = 0x05; | ||
762 | s5_rsp.command = SSH_SOCKS5_SUCCESS; | ||
763 | s5_rsp.reserved = 0; /* ignored */ | ||
764 | s5_rsp.atyp = SSH_SOCKS5_IPV4; | ||
765 | ((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY; | ||
766 | dest_port = 0; /* ignored */ | ||
767 | |||
768 | buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp)); | ||
769 | buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr)); | ||
770 | buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port)); | ||
771 | return 1; | ||
772 | } | ||
773 | |||
774 | /* dynamic port forwarding */ | 615 | /* dynamic port forwarding */ |
775 | void | 616 | void |
776 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | 617 | channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) |
@@ -791,15 +632,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) | |||
791 | /* try to guess the protocol */ | 632 | /* try to guess the protocol */ |
792 | p = buffer_ptr(&c->input); | 633 | p = buffer_ptr(&c->input); |
793 | switch (p[0]) { | 634 | switch (p[0]) { |
794 | case 'C': | ||
795 | ret = channel_decode_https(c, readset, writeset); | ||
796 | break; | ||
797 | case 0x04: | 635 | case 0x04: |
798 | ret = channel_decode_socks4(c, readset, writeset); | 636 | ret = channel_decode_socks4(c, readset, writeset); |
799 | break; | 637 | break; |
800 | case 0x05: | ||
801 | ret = channel_decode_socks5(c, readset, writeset); | ||
802 | break; | ||
803 | default: | 638 | default: |
804 | ret = -1; | 639 | ret = -1; |
805 | break; | 640 | break; |
@@ -39,7 +39,7 @@ | |||
39 | */ | 39 | */ |
40 | 40 | ||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | RCSID("$OpenBSD: ssh.c,v 1.115 2001/04/14 16:33:20 stevesk Exp $"); | 42 | RCSID("$OpenBSD: ssh.c,v 1.116 2001/04/17 12:55:04 markus Exp $"); |
43 | 43 | ||
44 | #include <openssl/evp.h> | 44 | #include <openssl/evp.h> |
45 | #include <openssl/err.h> | 45 | #include <openssl/err.h> |
@@ -182,10 +182,6 @@ usage(void) | |||
182 | fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); | 182 | fprintf(stderr, " -R listen-port:host:port Forward remote port to local address\n"); |
183 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); | 183 | fprintf(stderr, " These cause %s to listen for connections on a port, and\n", __progname); |
184 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); | 184 | fprintf(stderr, " forward them to the other side by connecting to host:port.\n"); |
185 | fprintf(stderr, " -D port Dynamically forward local port to multiple remote addresses.\n"); | ||
186 | fprintf(stderr, " Allows %s to act as an application-layer proxy.\n", | ||
187 | __progname); | ||
188 | fprintf(stderr, " Protocols supported: SOCKS4, SOCKS5, HTTPS\n"); | ||
189 | fprintf(stderr, " -C Enable compression.\n"); | 185 | fprintf(stderr, " -C Enable compression.\n"); |
190 | fprintf(stderr, " -N Do not execute a shell or command.\n"); | 186 | fprintf(stderr, " -N Do not execute a shell or command.\n"); |
191 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); | 187 | fprintf(stderr, " -g Allow remote hosts to connect to forwarded ports.\n"); |