]> Joshua Wise's Git repositories - dumload.git/blame - src/com/jcraft/jsch/ChannelForwardedTCPIP.java
Initial commit.
[dumload.git] / src / com / jcraft / jsch / ChannelForwardedTCPIP.java
CommitLineData
0763e16d
JW
1/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2/*
3Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7
8 1. Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in
13 the documentation and/or other materials provided with the distribution.
14
15 3. The names of the authors may not be used to endorse or promote products
16 derived from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
19INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
21INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
22INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30package com.jcraft.jsch;
31
32import java.net.*;
33import java.io.*;
34
35public class ChannelForwardedTCPIP extends Channel{
36
37 static java.util.Vector pool=new java.util.Vector();
38
39 static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
40//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
41 static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
42
43 static private final int TIMEOUT=10*1000;
44
45 SocketFactory factory=null;
46 private Socket socket=null;
47 private ForwardedTCPIPDaemon daemon=null;
48 String target;
49 int lport;
50 int rport;
51
52 ChannelForwardedTCPIP(){
53 super();
54 setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
55 setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
56 setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
57 io=new IO();
58 connected=true;
59 }
60
61 public void run(){
62 try{
63 if(lport==-1){
64 Class c=Class.forName(target);
65 daemon=(ForwardedTCPIPDaemon)c.newInstance();
66
67 PipedOutputStream out=new PipedOutputStream();
68 io.setInputStream(new PassiveInputStream(out
69 , 32*1024
70 ), false);
71
72 daemon.setChannel(this, getInputStream(), out);
73 Object[] foo=getPort(getSession(), rport);
74 daemon.setArg((Object[])foo[3]);
75
76 new Thread(daemon).start();
77 }
78 else{
79 socket=(factory==null) ?
80 Util.createSocket(target, lport, TIMEOUT) :
81 factory.createSocket(target, lport);
82 socket.setTcpNoDelay(true);
83 io.setInputStream(socket.getInputStream());
84 io.setOutputStream(socket.getOutputStream());
85 }
86 sendOpenConfirmation();
87 }
88 catch(Exception e){
89 sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
90 close=true;
91 disconnect();
92 return;
93 }
94
95 thread=Thread.currentThread();
96 Buffer buf=new Buffer(rmpsize);
97 Packet packet=new Packet(buf);
98 int i=0;
99 try{
100 while(thread!=null &&
101 io!=null &&
102 io.in!=null){
103 i=io.in.read(buf.buffer,
104 14,
105 buf.buffer.length-14
106 -32 -20 // padding and mac
107 );
108 if(i<=0){
109 eof();
110 break;
111 }
112 packet.reset();
113 if(close)break;
114 buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
115 buf.putInt(recipient);
116 buf.putInt(i);
117 buf.skip(i);
118 getSession().write(packet, this, i);
119 }
120 }
121 catch(Exception e){
122 //System.err.println(e);
123 }
124 //thread=null;
125 //eof();
126 disconnect();
127 }
128
129 void getData(Buffer buf){
130 setRecipient(buf.getInt());
131 setRemoteWindowSize(buf.getUInt());
132 setRemotePacketSize(buf.getInt());
133 byte[] addr=buf.getString();
134 int port=buf.getInt();
135 byte[] orgaddr=buf.getString();
136 int orgport=buf.getInt();
137
138 /*
139 System.err.println("addr: "+Util.byte2str(addr));
140 System.err.println("port: "+port);
141 System.err.println("orgaddr: "+Util.byte2str(orgaddr));
142 System.err.println("orgport: "+orgport);
143 */
144
145 Session _session=null;
146 try{
147 _session=getSession();
148 }
149 catch(JSchException e){
150 // session has been already down.
151 }
152
153 synchronized(pool){
154 for(int i=0; i<pool.size(); i++){
155 Object[] foo=(Object[])(pool.elementAt(i));
156 if(foo[0]!=_session) continue;
157 if(((Integer)foo[1]).intValue()!=port) continue;
158 this.rport=port;
159 this.target=(String)foo[2];
160 if(foo[3]==null || (foo[3] instanceof Object[])){ this.lport=-1; }
161 else{ this.lport=((Integer)foo[3]).intValue(); }
162 if(foo.length>=6){
163 this.factory=((SocketFactory)foo[5]);
164 }
165 break;
166 }
167 if(target==null){
168 //System.err.println("??");
169 }
170 }
171 }
172
173 static Object[] getPort(Session session, int rport){
174 synchronized(pool){
175 for(int i=0; i<pool.size(); i++){
176 Object[] bar=(Object[])(pool.elementAt(i));
177 if(bar[0]!=session) continue;
178 if(((Integer)bar[1]).intValue()!=rport) continue;
179 return bar;
180 }
181 return null;
182 }
183 }
184
185 static String[] getPortForwarding(Session session){
186 java.util.Vector foo=new java.util.Vector();
187 synchronized(pool){
188 for(int i=0; i<pool.size(); i++){
189 Object[] bar=(Object[])(pool.elementAt(i));
190 if(bar[0]!=session) continue;
191 if(bar[3]==null){ foo.addElement(bar[1]+":"+bar[2]+":"); }
192 else{ foo.addElement(bar[1]+":"+bar[2]+":"+bar[3]); }
193 }
194 }
195 String[] bar=new String[foo.size()];
196 for(int i=0; i<foo.size(); i++){
197 bar[i]=(String)(foo.elementAt(i));
198 }
199 return bar;
200 }
201
202 static String normalize(String address){
203 if(address==null){ return "localhost"; }
204 else if(address.length()==0 || address.equals("*")){ return ""; }
205 else{ return address; }
206 }
207
208 static void addPort(Session session, String _address_to_bind, int port, String target, int lport, SocketFactory factory) throws JSchException{
209 String address_to_bind=normalize(_address_to_bind);
210 synchronized(pool){
211 if(getPort(session, port)!=null){
212 throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
213 }
214 Object[] foo=new Object[6];
215 foo[0]=session; foo[1]=new Integer(port);
216 foo[2]=target; foo[3]=new Integer(lport);
217 foo[4]=address_to_bind;
218 foo[5]=factory;
219 pool.addElement(foo);
220 }
221 }
222 static void addPort(Session session, String _address_to_bind, int port, String daemon, Object[] arg) throws JSchException{
223 String address_to_bind=normalize(_address_to_bind);
224 synchronized(pool){
225 if(getPort(session, port)!=null){
226 throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
227 }
228 Object[] foo=new Object[5];
229 foo[0]=session; foo[1]=new Integer(port);
230 foo[2]=daemon; foo[3]=arg;
231 foo[4]=address_to_bind;
232 pool.addElement(foo);
233 }
234 }
235 static void delPort(ChannelForwardedTCPIP c){
236 Session _session=null;
237 try{
238 _session=c.getSession();
239 }
240 catch(JSchException e){
241 // session has been already down.
242 }
243 if(_session!=null)
244 delPort(_session, c.rport);
245 }
246 static void delPort(Session session, int rport){
247 delPort(session, null, rport);
248 }
249 static void delPort(Session session, String address_to_bind, int rport){
250 synchronized(pool){
251 Object[] foo=null;
252 for(int i=0; i<pool.size(); i++){
253 Object[] bar=(Object[])(pool.elementAt(i));
254 if(bar[0]!=session) continue;
255 if(((Integer)bar[1]).intValue()!=rport) continue;
256 foo=bar;
257 break;
258 }
259 if(foo==null)return;
260 pool.removeElement(foo);
261 if(address_to_bind==null){
262 address_to_bind=(String)foo[4];
263 }
264 if(address_to_bind==null){
265 address_to_bind="0.0.0.0";
266 }
267 }
268
269 Buffer buf=new Buffer(100); // ??
270 Packet packet=new Packet(buf);
271
272 try{
273 // byte SSH_MSG_GLOBAL_REQUEST 80
274 // string "cancel-tcpip-forward"
275 // boolean want_reply
276 // string address_to_bind (e.g. "127.0.0.1")
277 // uint32 port number to bind
278 packet.reset();
279 buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
280 buf.putString(Util.str2byte("cancel-tcpip-forward"));
281 buf.putByte((byte)0);
282 buf.putString(Util.str2byte(address_to_bind));
283 buf.putInt(rport);
284 session.write(packet);
285 }
286 catch(Exception e){
287// throw new JSchException(e.toString());
288 }
289 }
290 static void delPort(Session session){
291 int[] rport=null;
292 int count=0;
293 synchronized(pool){
294 rport=new int[pool.size()];
295 for(int i=0; i<pool.size(); i++){
296 Object[] bar=(Object[])(pool.elementAt(i));
297 if(bar[0]==session) {
298 rport[count++]=((Integer)bar[1]).intValue();
299 }
300 }
301 }
302 for(int i=0; i<count; i++){
303 delPort(session, rport[i]);
304 }
305 }
306
307 public int getRemotePort(){return rport;}
308 void setSocketFactory(SocketFactory factory){
309 this.factory=factory;
310 }
311}
This page took 0.047155 seconds and 4 git commands to generate.