annotate svr-tcpfwd.c @ 70:b0316ce64e4b

Merging in the changes from 0.41-0.43 main Dropbear tree
author Matt Johnston <matt@ucc.asn.au>
date Thu, 12 Aug 2004 16:41:58 +0000
parents efb5e0b335cf
children e3adf4cf5465
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 #include "includes.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 #include "ssh.h"
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
3 #include "tcpfwd.h"
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 #include "dbutil.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 #include "session.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 #include "buffer.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 #include "packet.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 #include "listener.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 #include "runopts.h"
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11 #ifndef DISABLE_SVR_REMOTETCPFWD
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 static void send_msg_request_success();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 static void send_msg_request_failure();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 static int svr_cancelremotetcp();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 static int svr_remotetcpreq();
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
17 static int newtcpdirect(struct Channel * channel);
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 const struct ChanType svr_chan_tcpdirect = {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 1, /* sepfds */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 "direct-tcpip",
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 newtcpdirect, /* init */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 NULL, /* checkclose */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 NULL, /* reqhandler */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 NULL /* closehandler */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 };
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 static const struct ChanType svr_chan_tcpremote = {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 1, /* sepfds */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 "forwarded-tcpip",
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 NULL,
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 NULL,
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 NULL,
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 NULL
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 };
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 /* At the moment this is completely used for tcp code (with the name reflecting
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 * that). If new request types are added, this should be replaced with code
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 * similar to the request-switching in chansession.c */
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 void recv_msg_global_request_remotetcp() {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43 unsigned char* reqname = NULL;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 unsigned int namelen;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 unsigned int wantreply = 0;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 int ret = DROPBEAR_FAILURE;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 TRACE(("enter recv_msg_global_request_remotetcp"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 if (opts.noremotetcp) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 TRACE(("leave recv_msg_global_request_remotetcp: remote tcp forwarding disabled"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55 reqname = buf_getstring(ses.payload, &namelen);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56 wantreply = buf_getbyte(ses.payload);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
58 if (namelen > MAXNAMLEN) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 TRACE(("name len is wrong: %d", namelen));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
60 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
61 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
63 if (strcmp("tcpip-forward", reqname) == 0) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64 ret = svr_remotetcpreq();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 } else if (strcmp("cancel-tcpip-forward", reqname) == 0) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66 ret = svr_cancelremotetcp();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 } else {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68 TRACE(("reqname isn't tcpip-forward: '%s'", reqname));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
70
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71 out:
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72 if (wantreply) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73 if (ret == DROPBEAR_SUCCESS) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 send_msg_request_success();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 } else {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76 send_msg_request_failure();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
77 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 m_free(reqname);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82 TRACE(("leave recv_msg_global_request"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
84
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
86 static void send_msg_request_success() {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88 CHECKCLEARTOWRITE();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 encrypt_packet();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 static void send_msg_request_failure() {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96 CHECKCLEARTOWRITE();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97 buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_FAILURE);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98 encrypt_packet();
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102 static int matchtcp(void* typedata1, void* typedata2) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
103
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104 const struct TCPListener *info1 = (struct TCPListener*)typedata1;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
105 const struct TCPListener *info2 = (struct TCPListener*)typedata2;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
107 return (info1->sendport == info2->sendport)
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 && (info1->chantype == info2->chantype)
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
109 && (strcmp(info1->sendaddr, info2->sendaddr) == 0);
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
110 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 static int svr_cancelremotetcp() {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
114 int ret = DROPBEAR_FAILURE;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
115 unsigned char * bindaddr = NULL;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 unsigned int addrlen;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 unsigned int port;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 struct Listener * listener = NULL;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 struct TCPListener tcpinfo;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121 TRACE(("enter cancelremotetcp"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
123 bindaddr = buf_getstring(ses.payload, &addrlen);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
124 if (addrlen > MAX_IP_LEN) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125 TRACE(("addr len too long: %d", addrlen));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
126 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
127 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
128
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
129 port = buf_getint(ses.payload);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
130
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
131 tcpinfo.sendaddr = bindaddr;
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
132 tcpinfo.sendport = port;
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 listener = get_listener(CHANNEL_ID_TCPFORWARDED, &tcpinfo, matchtcp);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 if (listener) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135 remove_listener( listener );
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
136 ret = DROPBEAR_SUCCESS;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
137 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139 out:
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 m_free(bindaddr);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141 TRACE(("leave cancelremotetcp"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142 return ret;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
144
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
145 static int svr_remotetcpreq() {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
146
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
147 int ret = DROPBEAR_FAILURE;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
148 unsigned char * bindaddr = NULL;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
149 unsigned int addrlen;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
150 struct TCPListener *tcpinfo = NULL;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
151 unsigned int port;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
152
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
153 TRACE(("enter remotetcpreq"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
154
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
155 /* NOTE: at this stage, we ignore bindaddr. see below and listen_tcpfwd */
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
156 bindaddr = buf_getstring(ses.payload, &addrlen);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
157 if (addrlen > MAX_IP_LEN) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
158 TRACE(("addr len too long: %d", addrlen));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
159 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
160 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
161
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
162 port = buf_getint(ses.payload);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
163
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
164 if (port == 0) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
165 dropbear_log(LOG_INFO, "Server chosen tcpfwd ports are unsupported");
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
166 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
167 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
168
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
169 if (port < 1 || port > 65535) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
170 TRACE(("invalid port: %d", port));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
171 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
172 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
173
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
174 if (!ses.allowprivport && port < IPPORT_RESERVED) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
175 TRACE(("can't assign port < 1024 for non-root"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
176 goto out;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
177 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
178
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
179 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
180 tcpinfo->sendaddr = bindaddr;
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
181 tcpinfo->sendport = port;
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
182 tcpinfo->listenport = port;
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
183 tcpinfo->chantype = &svr_chan_tcpremote;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
184
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
185 /* Note: bindaddr is actually ignored by listen_tcpfwd, since
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
186 * we only want to bind to localhost */
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
187 ret = listen_tcpfwd(tcpinfo);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
188
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
189 out:
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
190 if (ret == DROPBEAR_FAILURE) {
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
191 /* we only free it if a listener wasn't created, since the listener
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
192 * has to remember it if it's to be cancelled */
63
dcc43965928f - A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents: 62
diff changeset
193 m_free(tcpinfo->sendaddr);
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
194 m_free(tcpinfo);
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
195 }
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
196 TRACE(("leave remotetcpreq"));
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
197 return ret;
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
198 }
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
199
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
200 /* Called upon creating a new direct tcp channel (ie we connect out to an
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
201 * address */
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
202 static int newtcpdirect(struct Channel * channel) {
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
203
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
204 unsigned char* desthost = NULL;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
205 unsigned int destport;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
206 unsigned char* orighost = NULL;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
207 unsigned int origport;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
208 char portstring[NI_MAXSERV];
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
209 int sock;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
210 int len;
70
b0316ce64e4b Merging in the changes from 0.41-0.43 main Dropbear tree
Matt Johnston <matt@ucc.asn.au>
parents: 64
diff changeset
211 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
212
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
213 if (opts.nolocaltcp) {
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
214 TRACE(("leave newtcpdirect: local tcp forwarding disabled"));
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
215 goto out;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
216 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
217
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
218 desthost = buf_getstring(ses.payload, &len);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
219 if (len > MAX_HOST_LEN) {
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
220 TRACE(("leave newtcpdirect: desthost too long"));
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
221 goto out;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
222 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
223
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
224 destport = buf_getint(ses.payload);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
225
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
226 orighost = buf_getstring(ses.payload, &len);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
227 if (len > MAX_HOST_LEN) {
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
228 TRACE(("leave newtcpdirect: orighost too long"));
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
229 goto out;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
230 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
231
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
232 origport = buf_getint(ses.payload);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
233
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
234 /* best be sure */
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
235 if (origport > 65535 || destport > 65535) {
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
236 TRACE(("leave newtcpdirect: port > 65535"));
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
237 goto out;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
238 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
239
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
240 snprintf(portstring, sizeof(portstring), "%d", destport);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
241 sock = connect_remote(desthost, portstring, 1, NULL);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
242 if (sock < 0) {
70
b0316ce64e4b Merging in the changes from 0.41-0.43 main Dropbear tree
Matt Johnston <matt@ucc.asn.au>
parents: 64
diff changeset
243 err = SSH_OPEN_CONNECT_FAILED;
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
244 TRACE(("leave newtcpdirect: sock failed"));
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
245 goto out;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
246 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
247
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
248 ses.maxfd = MAX(ses.maxfd, sock);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
249
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
250 /* Note that infd is actually the "outgoing" direction on the
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
251 * tcp connection, vice versa for outfd.
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
252 * We don't set outfd, that will get set after the connection's
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
253 * progress succeeds */
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
254 channel->infd = sock;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
255 channel->initconn = 1;
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
256
70
b0316ce64e4b Merging in the changes from 0.41-0.43 main Dropbear tree
Matt Johnston <matt@ucc.asn.au>
parents: 64
diff changeset
257 err = SSH_OPEN_IN_PROGRESS;
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
258
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
259 out:
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
260 m_free(desthost);
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
261 m_free(orighost);
70
b0316ce64e4b Merging in the changes from 0.41-0.43 main Dropbear tree
Matt Johnston <matt@ucc.asn.au>
parents: 64
diff changeset
262 TRACE(("leave newtcpdirect: err %d", err));
b0316ce64e4b Merging in the changes from 0.41-0.43 main Dropbear tree
Matt Johnston <matt@ucc.asn.au>
parents: 64
diff changeset
263 return err;
64
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
264 }
efb5e0b335cf TCP forwarding works.
Matt Johnston <matt@ucc.asn.au>
parents: 63
diff changeset
265
62
20563735e8b5 just checkpointing
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
266 #endif