Mercurial > dropbear
annotate tcp-accept.c @ 1715:3974f087d9c0
Disallow leading lines before the ident for server (#102)
Per RFC4253 4.2 clients must be able to process other lines of data
before the version string, server behavior is not defined neither
with MUST/SHOULD nor with MAY.
If server process up to 50 lines too - it may cause too long hanging
session with invalid/evil client that consume host resources and
potentially may lead to DDoS on poor embedded boxes.
Let's require first line from client to be version string and fail
early if it's not - matches both RFC and real OpenSSH behavior.
author | Vladislav Grishenko <themiron@users.noreply.github.com> |
---|---|
date | Mon, 15 Jun 2020 18:22:18 +0500 |
parents | 572a7aefa188 |
children | 1d86a58fb52d |
rev | line source |
---|---|
74
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
1 /* |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
2 * Dropbear SSH |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
3 * |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
4 * Copyright (c) 2002,2003 Matt Johnston |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
5 * All rights reserved. |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
6 * |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
7 * Permission is hereby granted, free of charge, to any person obtaining a copy |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
8 * of this software and associated documentation files (the "Software"), to deal |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
9 * in the Software without restriction, including without limitation the rights |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
11 * copies of the Software, and to permit persons to whom the Software is |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
12 * furnished to do so, subject to the following conditions: |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
13 * |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
14 * The above copyright notice and this permission notice shall be included in |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
15 * all copies or substantial portions of the Software. |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
16 * |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
23 * SOFTWARE. */ |
e3adf4cf5465
License boilerplate etc, add Mihnea as an author to some of the files
Matt Johnston <matt@ucc.asn.au>
parents:
65
diff
changeset
|
24 |
62 | 25 #include "includes.h" |
26 #include "ssh.h" | |
64 | 27 #include "tcpfwd.h" |
62 | 28 #include "dbutil.h" |
29 #include "session.h" | |
30 #include "buffer.h" | |
31 #include "packet.h" | |
32 #include "listener.h" | |
941
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
33 #include "listener.h" |
62 | 34 #include "runopts.h" |
35 | |
1295
750ec4ec4cbe
Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents:
1237
diff
changeset
|
36 #if DROPBEAR_TCP_ACCEPT |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
37 |
1460
58a74cb829b8
Pointer parameter could be declared as pointing to const (callback)
Francois Perrad <francois.perrad@gadz.org>
parents:
1403
diff
changeset
|
38 static void cleanup_tcp(const struct Listener *listener) { |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
39 |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
40 struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata); |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
41 |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
42 m_free(tcpinfo->sendaddr); |
258
306499676384
* add -g (dbclient) and -a (dropbear) options for allowing non-local
Matt Johnston <matt@ucc.asn.au>
parents:
165
diff
changeset
|
43 m_free(tcpinfo->listenaddr); |
675
dfdb9d9189ff
Server shouldn't return "localhost" in response to -R forward connections
Matt Johnston <matt@ucc.asn.au>
parents:
632
diff
changeset
|
44 m_free(tcpinfo->request_listenaddr); |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
45 m_free(tcpinfo); |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
46 } |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
47 |
941
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
48 int tcp_prio_inithandler(struct Channel* channel) |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
49 { |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
50 TRACE(("tcp_prio_inithandler channel %d", channel->index)) |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
51 channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE; |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
52 return 0; |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
53 } |
5daedffd0769
Set tcp priority as follows:
Matt Johnston <matt@ucc.asn.au>
parents:
675
diff
changeset
|
54 |
1460
58a74cb829b8
Pointer parameter could be declared as pointing to const (callback)
Francois Perrad <francois.perrad@gadz.org>
parents:
1403
diff
changeset
|
55 static void tcp_acceptor(const struct Listener *listener, int sock) { |
62 | 56 |
57 int fd; | |
1403
ae6887d9ab46
rename hidden variable
Francois Perrad <francois.perrad@gadz.org>
parents:
1295
diff
changeset
|
58 struct sockaddr_storage sa; |
276
3cea9d789cca
Stomp on some minor warnings
Matt Johnston <matt@ucc.asn.au>
parents:
259
diff
changeset
|
59 socklen_t len; |
62 | 60 char ipstring[NI_MAXHOST], portstring[NI_MAXSERV]; |
61 struct TCPListener *tcpinfo = (struct TCPListener*)(listener->typedata); | |
62 | |
1403
ae6887d9ab46
rename hidden variable
Francois Perrad <francois.perrad@gadz.org>
parents:
1295
diff
changeset
|
63 len = sizeof(sa); |
62 | 64 |
1403
ae6887d9ab46
rename hidden variable
Francois Perrad <francois.perrad@gadz.org>
parents:
1295
diff
changeset
|
65 fd = accept(sock, (struct sockaddr*)&sa, &len); |
62 | 66 if (fd < 0) { |
67 return; | |
68 } | |
69 | |
1403
ae6887d9ab46
rename hidden variable
Francois Perrad <francois.perrad@gadz.org>
parents:
1295
diff
changeset
|
70 if (getnameinfo((struct sockaddr*)&sa, len, ipstring, sizeof(ipstring), |
62 | 71 portstring, sizeof(portstring), |
72 NI_NUMERICHOST | NI_NUMERICSERV) != 0) { | |
621
d2daeb015138
Clean up leaked FD if getnameinfo fails. From Klocwork
Matt Johnston <matt@ucc.asn.au>
parents:
577
diff
changeset
|
73 m_close(fd); |
62 | 74 return; |
75 } | |
76 | |
77 if (send_msg_channel_open_init(fd, tcpinfo->chantype) == DROPBEAR_SUCCESS) { | |
1109
2c646a65a1e3
Turn addr local variable into char *
Gaël PORTAY <gael.portay@gmail.com>
parents:
1094
diff
changeset
|
78 char* addr = NULL; |
259
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
79 unsigned int port = 0; |
62 | 80 |
259
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
81 if (tcpinfo->tcp_type == direct) { |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
82 /* "direct-tcpip" */ |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
83 /* host to connect, port to connect */ |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
84 addr = tcpinfo->sendaddr; |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
85 port = tcpinfo->sendport; |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
86 } else { |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
87 dropbear_assert(tcpinfo->tcp_type == forwarded); |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
88 /* "forwarded-tcpip" */ |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
89 /* address that was connected, port that was connected */ |
675
dfdb9d9189ff
Server shouldn't return "localhost" in response to -R forward connections
Matt Johnston <matt@ucc.asn.au>
parents:
632
diff
changeset
|
90 addr = tcpinfo->request_listenaddr; |
259
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
91 port = tcpinfo->listenport; |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
92 } |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
93 |
632
abf040aedd44
Fix crash with -R forwarding
Matt Johnston <matt@ucc.asn.au>
parents:
621
diff
changeset
|
94 if (addr == NULL) { |
abf040aedd44
Fix crash with -R forwarding
Matt Johnston <matt@ucc.asn.au>
parents:
621
diff
changeset
|
95 addr = "localhost"; |
abf040aedd44
Fix crash with -R forwarding
Matt Johnston <matt@ucc.asn.au>
parents:
621
diff
changeset
|
96 } |
1123
d7b752525b91
buf_getstring and buf_putstring now use non-unsigned char*
Matt Johnston <matt@ucc.asn.au>
parents:
1109
diff
changeset
|
97 buf_putstring(ses.writepayload, addr, strlen(addr)); |
259
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
98 buf_putint(ses.writepayload, port); |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
99 |
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
100 /* originator ip */ |
1123
d7b752525b91
buf_getstring and buf_putstring now use non-unsigned char*
Matt Johnston <matt@ucc.asn.au>
parents:
1109
diff
changeset
|
101 buf_putstring(ses.writepayload, ipstring, strlen(ipstring)); |
259
c049490e43fe
* fix -L forwarding on the client, broke last rev
Matt Johnston <matt@ucc.asn.au>
parents:
258
diff
changeset
|
102 /* originator port */ |
62 | 103 buf_putint(ses.writepayload, atol(portstring)); |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
104 |
62 | 105 encrypt_packet(); |
106 | |
107 } else { | |
108 /* XXX debug? */ | |
109 close(fd); | |
110 } | |
111 } | |
112 | |
1620
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
113 int listen_tcpfwd(struct TCPListener* tcpinfo, struct Listener **ret_listener) { |
62 | 114 |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
115 char portstring[NI_MAXSERV]; |
62 | 116 int socks[DROPBEAR_MAX_SOCKS]; |
117 int nsocks; | |
1620
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
118 struct Listener *listener; |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
119 char* errstring = NULL; |
62 | 120 |
165
0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents:
74
diff
changeset
|
121 TRACE(("enter listen_tcpfwd")) |
62 | 122 |
123 /* first we try to bind, so don't need to do so much cleanup on failure */ | |
1237
888e3d17e962
Fix print format specifier
Chocobo1 <Chocobo1@users.noreply.github.com>
parents:
1123
diff
changeset
|
124 snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport); |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
125 |
577
69e98c45db7c
- Progress for allowing specifying a listenaddr for tcp forwards
Matt Johnston <matt@ucc.asn.au>
parents:
433
diff
changeset
|
126 nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks, |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
127 DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd); |
62 | 128 if (nsocks < 0) { |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
129 dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring); |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
130 m_free(errstring); |
165
0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents:
74
diff
changeset
|
131 TRACE(("leave listen_tcpfwd: dropbear_listen failed")) |
62 | 132 return DROPBEAR_FAILURE; |
133 } | |
371
6aea2cfc113e
Fix memory leak found by Klocwork
Matt Johnston <matt@ucc.asn.au>
parents:
276
diff
changeset
|
134 m_free(errstring); |
6aea2cfc113e
Fix memory leak found by Klocwork
Matt Johnston <matt@ucc.asn.au>
parents:
276
diff
changeset
|
135 |
6aea2cfc113e
Fix memory leak found by Klocwork
Matt Johnston <matt@ucc.asn.au>
parents:
276
diff
changeset
|
136 /* new_listener will close the socks if it fails */ |
62 | 137 listener = new_listener(socks, nsocks, CHANNEL_ID_TCPFORWARDED, tcpinfo, |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
138 tcp_acceptor, cleanup_tcp); |
62 | 139 |
140 if (listener == NULL) { | |
165
0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents:
74
diff
changeset
|
141 TRACE(("leave listen_tcpfwd: listener failed")) |
62 | 142 return DROPBEAR_FAILURE; |
143 } | |
144 | |
1620
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
145 if (ret_listener) { |
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
146 *ret_listener = listener; |
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
147 } |
572a7aefa188
FIx remote forward listeners
Matt Johnston <matt@ucc.asn.au>
parents:
1460
diff
changeset
|
148 |
165
0cfba3034be5
Fixed DEBUG_TRACE macro so that we don't get semicolons left about the place
Matt Johnston <matt@ucc.asn.au>
parents:
74
diff
changeset
|
149 TRACE(("leave listen_tcpfwd: success")) |
62 | 150 return DROPBEAR_SUCCESS; |
151 } | |
152 | |
65
02e4a7f614f8
Oops, forgot to call the actual code.
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
153 #endif /* DROPBEAR_TCP_ACCEPT */ |