comparison cli-tcpfwd.c @ 118:5312ca05ed48 private-rez

propagate of 717950f4061f1123659ee87c7c168805af920ab7 and 839f98f136788cc1466e4641bf796f96040a085d from branch 'matt.dbclient.authpam' to 'matt.dbclient.rez'
author Matt Johnston <matt@ucc.asn.au>
date Sun, 12 Sep 2004 04:56:50 +0000
parents 10f4d3319780
children 8c2b3506f112
comparison
equal deleted inserted replaced
57:3b2a5a1c4347 118:5312ca05ed48
1 /*
2 * Dropbear SSH
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
24
25 #include "includes.h"
26 #include "options.h"
27 #include "dbutil.h"
28 #include "tcpfwd.h"
29 #include "channel.h"
30 #include "runopts.h"
31 #include "session.h"
32 #include "ssh.h"
33
34 static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
35 unsigned int remoteport);
36 static int newtcpforwarded(struct Channel * channel);
37
38 const struct ChanType cli_chan_tcpremote = {
39 1, /* sepfds */
40 "forwarded-tcpip",
41 newtcpforwarded,
42 NULL,
43 NULL,
44 NULL
45 };
46 static const struct ChanType cli_chan_tcplocal = {
47 1, /* sepfds */
48 "direct-tcpip",
49 NULL,
50 NULL,
51 NULL,
52 NULL
53 };
54
55 void setup_localtcp() {
56
57 int ret;
58
59 TRACE(("enter setup_localtcp"));
60
61 if (cli_opts.localfwds == NULL) {
62 TRACE(("cli_opts.localfwds == NULL"));
63 }
64
65 while (cli_opts.localfwds != NULL) {
66 ret = cli_localtcp(cli_opts.localfwds->listenport,
67 cli_opts.localfwds->connectaddr,
68 cli_opts.localfwds->connectport);
69 if (ret == DROPBEAR_FAILURE) {
70 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d",
71 cli_opts.localfwds->listenport,
72 cli_opts.localfwds->connectaddr,
73 cli_opts.localfwds->connectport);
74 }
75
76 cli_opts.localfwds = cli_opts.localfwds->next;
77 }
78 TRACE(("leave setup_localtcp"));
79
80 }
81
82 static int cli_localtcp(unsigned int listenport, const char* remoteaddr,
83 unsigned int remoteport) {
84
85 struct TCPListener* tcpinfo = NULL;
86 int ret;
87
88 TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr,
89 remoteport));
90
91 tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener*));
92 tcpinfo->sendaddr = m_strdup(remoteaddr);
93 tcpinfo->sendport = remoteport;
94 tcpinfo->listenport = listenport;
95 tcpinfo->chantype = &cli_chan_tcplocal;
96
97 ret = listen_tcpfwd(tcpinfo);
98
99 if (ret == DROPBEAR_FAILURE) {
100 m_free(tcpinfo);
101 }
102 TRACE(("leave cli_localtcp: %d", ret));
103 return ret;
104 }
105
106 static void send_msg_global_request_remotetcp(int port) {
107
108 TRACE(("enter send_msg_global_request_remotetcp"));
109
110 CHECKCLEARTOWRITE();
111 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST);
112 buf_putstring(ses.writepayload, "tcpip-forward", 13);
113 buf_putbyte(ses.writepayload, 0);
114 buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */
115 buf_putint(ses.writepayload, port);
116
117 encrypt_packet();
118
119 TRACE(("leave send_msg_global_request_remotetcp"));
120 }
121
122 void setup_remotetcp() {
123
124 struct TCPFwdList * iter = NULL;
125
126 TRACE(("enter setup_remotetcp"));
127
128 if (cli_opts.remotefwds == NULL) {
129 TRACE(("cli_opts.remotefwds == NULL"));
130 }
131
132 iter = cli_opts.remotefwds;
133
134 while (iter != NULL) {
135 send_msg_global_request_remotetcp(iter->listenport);
136 iter = iter->next;
137 }
138 TRACE(("leave setup_remotetcp"));
139 }
140
141 static int newtcpforwarded(struct Channel * channel) {
142
143 unsigned int origport;
144 struct TCPFwdList * iter = NULL;
145 char portstring[NI_MAXSERV];
146 int sock;
147 int err = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
148
149 /* We don't care what address they connected to */
150 buf_eatstring(ses.payload);
151
152 origport = buf_getint(ses.payload);
153
154 /* Find which port corresponds */
155 iter = cli_opts.remotefwds;
156
157 while (iter != NULL) {
158 if (origport == iter->listenport) {
159 break;
160 }
161 iter = iter->next;
162 }
163
164 if (iter == NULL) {
165 /* We didn't request forwarding on that port */
166 dropbear_log(LOG_INFO, "Server send unrequested port, from port %d",
167 origport);
168 goto out;
169 }
170
171 snprintf(portstring, sizeof(portstring), "%d", iter->connectport);
172 sock = connect_remote(iter->connectaddr, portstring, 1, NULL);
173 if (sock < 0) {
174 TRACE(("leave newtcpdirect: sock failed"));
175 err = SSH_OPEN_CONNECT_FAILED;
176 goto out;
177 }
178
179 ses.maxfd = MAX(ses.maxfd, sock);
180
181 /* Note that infd is actually the "outgoing" direction on the
182 * tcp connection, vice versa for outfd.
183 * We don't set outfd, that will get set after the connection's
184 * progress succeeds */
185 channel->infd = sock;
186 channel->initconn = 1;
187
188 err = SSH_OPEN_IN_PROGRESS;
189
190 out:
191 TRACE(("leave newtcpdirect: err %d", err));
192 return err;
193 }