Mercurial > dropbear
annotate cli-tcpfwd.c @ 67:86725004a0ea
fake-rfc stuff
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 14:39:17 +0000 |
parents | 38c3146aa23d |
children | b0316ce64e4b |
rev | line source |
---|---|
62 | 1 #include "includes.h" |
2 #include "options.h" | |
64 | 3 #include "dbutil.h" |
4 #include "tcpfwd.h" | |
62 | 5 #include "channel.h" |
64 | 6 #include "runopts.h" |
7 #include "session.h" | |
8 #include "ssh.h" | |
62 | 9 |
64 | 10 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, |
11 unsigned int remoteport); | |
12 static int newtcpforwarded(struct Channel * channel); | |
13 | |
14 const struct ChanType cli_chan_tcpremote = { | |
15 1, /* sepfds */ | |
16 "forwarded-tcpip", | |
17 newtcpforwarded, | |
18 NULL, | |
19 NULL, | |
20 NULL | |
21 }; | |
62 | 22 static const struct ChanType cli_chan_tcplocal = { |
23 1, /* sepfds */ | |
24 "direct-tcpip", | |
25 NULL, | |
26 NULL, | |
64 | 27 NULL, |
62 | 28 NULL |
29 }; | |
30 | |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
31 void setup_localtcp() { |
62 | 32 |
64 | 33 int ret; |
34 | |
66
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
35 TRACE(("enter setup_localtcp")); |
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
36 |
64 | 37 if (cli_opts.localfwds == NULL) { |
38 TRACE(("cli_opts.localfwds == NULL")); | |
39 } | |
40 | |
41 while (cli_opts.localfwds != NULL) { | |
42 ret = cli_localtcp(cli_opts.localfwds->listenport, | |
43 cli_opts.localfwds->connectaddr, | |
44 cli_opts.localfwds->connectport); | |
45 if (ret == DROPBEAR_FAILURE) { | |
46 dropbear_log(LOG_WARNING, "Failed local port forward %d:%s:%d", | |
47 cli_opts.localfwds->listenport, | |
48 cli_opts.localfwds->connectaddr, | |
49 cli_opts.localfwds->connectport); | |
50 } | |
51 | |
52 cli_opts.localfwds = cli_opts.localfwds->next; | |
53 } | |
66
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
54 TRACE(("leave setup_localtcp")); |
62 | 55 |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
56 } |
62 | 57 |
63
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
58 static int cli_localtcp(unsigned int listenport, const char* remoteaddr, |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
59 unsigned int remoteport) { |
62 | 60 |
61 struct TCPListener* tcpinfo = NULL; | |
64 | 62 int ret; |
63 | |
64 TRACE(("enter cli_localtcp: %d %s %d", listenport, remoteaddr, | |
65 remoteport)); | |
62 | 66 |
67 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
|
68 tcpinfo->sendaddr = remoteaddr; |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
69 tcpinfo->sendport = remoteport; |
dcc43965928f
- A nice cleaner structure for tcp (acceptor) forwarding.
Matt Johnston <matt@ucc.asn.au>
parents:
62
diff
changeset
|
70 tcpinfo->listenport = listenport; |
62 | 71 tcpinfo->chantype = &cli_chan_tcplocal; |
72 | |
73 ret = listen_tcpfwd(tcpinfo); | |
74 | |
75 if (ret == DROPBEAR_FAILURE) { | |
76 m_free(tcpinfo); | |
77 } | |
64 | 78 TRACE(("leave cli_localtcp: %d", ret)); |
62 | 79 return ret; |
80 } | |
64 | 81 |
82 static void send_msg_global_request_remotetcp(int port) { | |
83 | |
84 TRACE(("enter send_msg_global_request_remotetcp")); | |
85 | |
86 CHECKCLEARTOWRITE(); | |
87 buf_putbyte(ses.writepayload, SSH_MSG_GLOBAL_REQUEST); | |
88 buf_putstring(ses.writepayload, "tcpip-forward", 13); | |
89 buf_putbyte(ses.writepayload, 0); | |
90 buf_putstring(ses.writepayload, "0.0.0.0", 7); /* TODO: IPv6? */ | |
91 buf_putint(ses.writepayload, port); | |
92 | |
93 encrypt_packet(); | |
94 | |
95 TRACE(("leave send_msg_global_request_remotetcp")); | |
96 } | |
97 | |
98 void setup_remotetcp() { | |
99 | |
100 struct TCPFwdList * iter = NULL; | |
101 | |
66
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
102 TRACE(("enter setup_remotetcp")); |
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
103 |
64 | 104 if (cli_opts.remotefwds == NULL) { |
105 TRACE(("cli_opts.remotefwds == NULL")); | |
106 } | |
107 | |
108 iter = cli_opts.remotefwds; | |
109 | |
110 while (iter != NULL) { | |
111 send_msg_global_request_remotetcp(iter->listenport); | |
112 iter = iter->next; | |
113 } | |
66
38c3146aa23d
Some more sanity-checking of args, and just warn and ignore OpenSSH args
Matt Johnston <matt@ucc.asn.au>
parents:
64
diff
changeset
|
114 TRACE(("leave setup_remotetcp")); |
64 | 115 } |
116 | |
117 static int newtcpforwarded(struct Channel * channel) { | |
118 | |
119 unsigned int origport; | |
120 struct TCPFwdList * iter = NULL; | |
121 char portstring[NI_MAXSERV]; | |
122 int sock; | |
123 int ret = DROPBEAR_FAILURE; | |
124 | |
125 /* We don't care what address they connected to */ | |
126 buf_eatstring(ses.payload); | |
127 | |
128 origport = buf_getint(ses.payload); | |
129 | |
130 /* Find which port corresponds */ | |
131 iter = cli_opts.remotefwds; | |
132 | |
133 while (iter != NULL) { | |
134 if (origport == iter->listenport) { | |
135 break; | |
136 } | |
137 iter = iter->next; | |
138 } | |
139 | |
140 if (iter == NULL) { | |
141 /* We didn't request forwarding on that port */ | |
142 dropbear_log(LOG_INFO, "Server send unrequested port, from port %d", | |
143 origport); | |
144 goto out; | |
145 } | |
146 | |
147 snprintf(portstring, sizeof(portstring), "%d", iter->connectport); | |
148 sock = connect_remote(iter->connectaddr, portstring, 1, NULL); | |
149 if (sock < 0) { | |
150 TRACE(("leave newtcpdirect: sock failed")); | |
151 goto out; | |
152 } | |
153 | |
154 ses.maxfd = MAX(ses.maxfd, sock); | |
155 | |
156 /* Note that infd is actually the "outgoing" direction on the | |
157 * tcp connection, vice versa for outfd. | |
158 * We don't set outfd, that will get set after the connection's | |
159 * progress succeeds */ | |
160 channel->infd = sock; | |
161 channel->initconn = 1; | |
162 | |
163 ret = DROPBEAR_SUCCESS; | |
164 | |
165 out: | |
166 TRACE(("leave newtcpdirect: ret %d", ret)); | |
167 return ret; | |
168 } |