comparison svr-tcpfwd.c @ 1464:ad637c9e0f6f

Server chosen tcpfwd ports (#43) Server chosen tcpfwd ports
author houseofkodai <karthik@houseofkodai.in>
date Thu, 25 Jan 2018 19:51:41 +0530
parents 58a74cb829b8
children f7a53832501d
comparison
equal deleted inserted replaced
1463:a3479d0d7e79 1464:ad637c9e0f6f
45 45
46 /* */ 46 /* */
47 #endif /* !DROPBEAR_SVR_REMOTETCPFWD */ 47 #endif /* !DROPBEAR_SVR_REMOTETCPFWD */
48 48
49 static int svr_cancelremotetcp(void); 49 static int svr_cancelremotetcp(void);
50 static int svr_remotetcpreq(void); 50 static int svr_remotetcpreq(int *allocated_listen_port);
51 static int newtcpdirect(struct Channel * channel); 51 static int newtcpdirect(struct Channel * channel);
52 52
53 #if DROPBEAR_SVR_REMOTETCPFWD 53 #if DROPBEAR_SVR_REMOTETCPFWD
54 static const struct ChanType svr_chan_tcpremote = { 54 static const struct ChanType svr_chan_tcpremote = {
55 1, /* sepfds */ 55 1, /* sepfds */
84 TRACE(("name len is wrong: %d", namelen)) 84 TRACE(("name len is wrong: %d", namelen))
85 goto out; 85 goto out;
86 } 86 }
87 87
88 if (strcmp("tcpip-forward", reqname) == 0) { 88 if (strcmp("tcpip-forward", reqname) == 0) {
89 ret = svr_remotetcpreq(); 89 int allocated_listen_port;
90 ret = svr_remotetcpreq(&allocated_listen_port);
91 /* client expects-port-number-to-make-use-of-server-allocated-ports */
92 if (DROPBEAR_SUCCESS == ret) {
93 CHECKCLEARTOWRITE();
94 buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS);
95 buf_putint(ses.writepayload, allocated_listen_port);
96 encrypt_packet();
97 wantreply = 0; //so out does not do so
98 }
90 } else if (strcmp("cancel-tcpip-forward", reqname) == 0) { 99 } else if (strcmp("cancel-tcpip-forward", reqname) == 0) {
91 ret = svr_cancelremotetcp(); 100 ret = svr_cancelremotetcp();
92 } else { 101 } else {
93 TRACE(("reqname isn't tcpip-forward: '%s'", reqname)) 102 TRACE(("reqname isn't tcpip-forward: '%s'", reqname))
94 } 103 }
150 m_free(bindaddr); 159 m_free(bindaddr);
151 TRACE(("leave cancelremotetcp")) 160 TRACE(("leave cancelremotetcp"))
152 return ret; 161 return ret;
153 } 162 }
154 163
155 static int svr_remotetcpreq() { 164 static int svr_remotetcpreq(int *allocated_listen_port) {
156 165
157 int ret = DROPBEAR_FAILURE; 166 int ret = DROPBEAR_FAILURE;
158 char * request_addr = NULL; 167 char * request_addr = NULL;
159 unsigned int addrlen; 168 unsigned int addrlen;
160 struct TCPListener *tcpinfo = NULL; 169 struct TCPListener *tcpinfo = NULL;
168 goto out; 177 goto out;
169 } 178 }
170 179
171 port = buf_getint(ses.payload); 180 port = buf_getint(ses.payload);
172 181
173 if (port == 0) { 182 if (port != 0) {
174 dropbear_log(LOG_INFO, "Server chosen tcpfwd ports are unsupported"); 183 if (port < 1 || port > 65535) {
175 goto out; 184 TRACE(("invalid port: %d", port))
176 } 185 goto out;
177 186 }
178 if (port < 1 || port > 65535) { 187
179 TRACE(("invalid port: %d", port)) 188 if (!ses.allowprivport && port < IPPORT_RESERVED) {
180 goto out; 189 TRACE(("can't assign port < 1024 for non-root"))
181 } 190 goto out;
182 191 }
183 if (!ses.allowprivport && port < IPPORT_RESERVED) {
184 TRACE(("can't assign port < 1024 for non-root"))
185 goto out;
186 } 192 }
187 193
188 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); 194 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
189 tcpinfo->sendaddr = NULL; 195 tcpinfo->sendaddr = NULL;
190 tcpinfo->sendport = 0; 196 tcpinfo->sendport = 0;
201 { 207 {
202 tcpinfo->listenaddr = m_strdup(request_addr); 208 tcpinfo->listenaddr = m_strdup(request_addr);
203 } 209 }
204 210
205 ret = listen_tcpfwd(tcpinfo); 211 ret = listen_tcpfwd(tcpinfo);
212 if (DROPBEAR_SUCCESS == ret) {
213 tcpinfo->listenport = get_sock_port(ses.listeners[0]->socks[0]);
214 *allocated_listen_port = tcpinfo->listenport;
215 dropbear_log(LOG_INFO, "tcpip-forward %s:%d '%s'",
216 ((NULL == tcpinfo->listenaddr)?"localhost":tcpinfo->listenaddr),
217 tcpinfo->listenport, ses.authstate.pw_name);
218 }
206 219
207 out: 220 out:
208 if (ret == DROPBEAR_FAILURE) { 221 if (ret == DROPBEAR_FAILURE) {
209 /* we only free it if a listener wasn't created, since the listener 222 /* we only free it if a listener wasn't created, since the listener
210 * has to remember it if it's to be cancelled */ 223 * has to remember it if it's to be cancelled */
211 m_free(request_addr); 224 m_free(request_addr);
212 m_free(tcpinfo); 225 m_free(tcpinfo);
213 } 226 }
227
214 TRACE(("leave remotetcpreq")) 228 TRACE(("leave remotetcpreq"))
229
215 return ret; 230 return ret;
216 } 231 }
217 232
218 #endif /* DROPBEAR_SVR_REMOTETCPFWD */ 233 #endif /* DROPBEAR_SVR_REMOTETCPFWD */
219 234