Mercurial > dropbear
comparison svr-tcpfwd.c @ 1478:3a933956437e coverity
update coverity
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 23:49:22 +0800 |
parents | f787f60f8e45 |
children | 2d450c1056e3 |
comparison
equal
deleted
inserted
replaced
1439:8d24733026c5 | 1478:3a933956437e |
---|---|
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 } |
105 m_free(reqname); | 114 m_free(reqname); |
106 | 115 |
107 TRACE(("leave recv_msg_global_request")) | 116 TRACE(("leave recv_msg_global_request")) |
108 } | 117 } |
109 | 118 |
110 static int matchtcp(void* typedata1, void* typedata2) { | 119 static int matchtcp(const void* typedata1, const void* typedata2) { |
111 | 120 |
112 const struct TCPListener *info1 = (struct TCPListener*)typedata1; | 121 const struct TCPListener *info1 = (struct TCPListener*)typedata1; |
113 const struct TCPListener *info2 = (struct TCPListener*)typedata2; | 122 const struct TCPListener *info2 = (struct TCPListener*)typedata2; |
114 | 123 |
115 return (info1->listenport == info2->listenport) | 124 return (info1->listenport == info2->listenport) |
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 |
268 TRACE(("leave newtcpdirect: port > 65535")) | 283 TRACE(("leave newtcpdirect: port > 65535")) |
269 goto out; | 284 goto out; |
270 } | 285 } |
271 | 286 |
272 snprintf(portstring, sizeof(portstring), "%u", destport); | 287 snprintf(portstring, sizeof(portstring), "%u", destport); |
273 channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel); | 288 channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL, NULL); |
274 | 289 |
275 channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE; | 290 channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE; |
276 | 291 |
277 err = SSH_OPEN_IN_PROGRESS; | 292 err = SSH_OPEN_IN_PROGRESS; |
278 | 293 |