Mercurial > dropbear
diff 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 |
line wrap: on
line diff
--- a/svr-tcpfwd.c Sat Jun 24 23:33:16 2017 +0800 +++ b/svr-tcpfwd.c Fri Feb 09 23:49:22 2018 +0800 @@ -47,7 +47,7 @@ #endif /* !DROPBEAR_SVR_REMOTETCPFWD */ static int svr_cancelremotetcp(void); -static int svr_remotetcpreq(void); +static int svr_remotetcpreq(int *allocated_listen_port); static int newtcpdirect(struct Channel * channel); #if DROPBEAR_SVR_REMOTETCPFWD @@ -86,7 +86,16 @@ } if (strcmp("tcpip-forward", reqname) == 0) { - ret = svr_remotetcpreq(); + int allocated_listen_port; + ret = svr_remotetcpreq(&allocated_listen_port); + /* client expects-port-number-to-make-use-of-server-allocated-ports */ + if (DROPBEAR_SUCCESS == ret) { + CHECKCLEARTOWRITE(); + buf_putbyte(ses.writepayload, SSH_MSG_REQUEST_SUCCESS); + buf_putint(ses.writepayload, allocated_listen_port); + encrypt_packet(); + wantreply = 0; //so out does not do so + } } else if (strcmp("cancel-tcpip-forward", reqname) == 0) { ret = svr_cancelremotetcp(); } else { @@ -107,7 +116,7 @@ TRACE(("leave recv_msg_global_request")) } -static int matchtcp(void* typedata1, void* typedata2) { +static int matchtcp(const void* typedata1, const void* typedata2) { const struct TCPListener *info1 = (struct TCPListener*)typedata1; const struct TCPListener *info2 = (struct TCPListener*)typedata2; @@ -152,7 +161,7 @@ return ret; } -static int svr_remotetcpreq() { +static int svr_remotetcpreq(int *allocated_listen_port) { int ret = DROPBEAR_FAILURE; char * request_addr = NULL; @@ -170,19 +179,16 @@ port = buf_getint(ses.payload); - if (port == 0) { - dropbear_log(LOG_INFO, "Server chosen tcpfwd ports are unsupported"); - goto out; - } + if (port != 0) { + if (port < 1 || port > 65535) { + TRACE(("invalid port: %d", port)) + goto out; + } - if (port < 1 || port > 65535) { - TRACE(("invalid port: %d", port)) - goto out; - } - - if (!ses.allowprivport && port < IPPORT_RESERVED) { - TRACE(("can't assign port < 1024 for non-root")) - goto out; + if (!ses.allowprivport && port < IPPORT_RESERVED) { + TRACE(("can't assign port < 1024 for non-root")) + goto out; + } } tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener)); @@ -203,6 +209,13 @@ } ret = listen_tcpfwd(tcpinfo); + if (DROPBEAR_SUCCESS == ret) { + tcpinfo->listenport = get_sock_port(ses.listeners[0]->socks[0]); + *allocated_listen_port = tcpinfo->listenport; + dropbear_log(LOG_INFO, "tcpip-forward %s:%d '%s'", + ((NULL == tcpinfo->listenaddr)?"localhost":tcpinfo->listenaddr), + tcpinfo->listenport, ses.authstate.pw_name); + } out: if (ret == DROPBEAR_FAILURE) { @@ -211,7 +224,9 @@ m_free(request_addr); m_free(tcpinfo); } + TRACE(("leave remotetcpreq")) + return ret; } @@ -270,7 +285,7 @@ } snprintf(portstring, sizeof(portstring), "%u", destport); - channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel); + channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL, NULL); channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;