ChannelForwardedTCPIP.java

Go to the documentation of this file.
00001 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
00002 /*
00003 Copyright (c) 2002-2011 ymnk, JCraft,Inc. All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008   1. Redistributions of source code must retain the above copyright notice,
00009      this list of conditions and the following disclaimer.
00010 
00011   2. Redistributions in binary form must reproduce the above copyright 
00012      notice, this list of conditions and the following disclaimer in 
00013      the documentation and/or other materials provided with the distribution.
00014 
00015   3. The names of the authors may not be used to endorse or promote products
00016      derived from this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
00021 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
00022 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00025 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00026 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00027 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 package com.jcraft.jsch;
00031 
00032 import java.net.*;
00033 import java.io.*;
00034 
00046 public class ChannelForwardedTCPIP extends Channel{
00047 
00048   static java.util.Vector pool=new java.util.Vector();
00049 
00050   static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
00051 //static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
00052   static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
00053 
00054   static private final int TIMEOUT=10*1000;
00055 
00056   SocketFactory factory=null;
00057   private Socket socket=null;
00058   private ForwardedTCPIPDaemon daemon=null;
00059   String target;
00060   int lport;
00061   int rport;
00062 
00063   ChannelForwardedTCPIP(){
00064     super();
00065     setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
00066     setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
00067     setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
00068     io=new IO();
00069     connected=true;
00070   }
00071 
00075   public void run(){
00076     try{ 
00077       if(lport==-1){
00078         Class c=Class.forName(target);
00079         daemon=(ForwardedTCPIPDaemon)c.newInstance();
00080 
00081         PipedOutputStream out=new PipedOutputStream();
00082         io.setInputStream(new PassiveInputStream(out
00083                                                  , 32*1024
00084                                                  ), false);
00085 
00086         daemon.setChannel(this, getInputStream(), out);
00087         Object[] foo=getPort(getSession(), rport);
00088         daemon.setArg((Object[])foo[3]);
00089 
00090         new Thread(daemon).start();
00091       }
00092       else{
00093         socket=(factory==null) ? 
00094            Util.createSocket(target, lport, TIMEOUT) : 
00095           factory.createSocket(target, lport);
00096         socket.setTcpNoDelay(true);
00097         io.setInputStream(socket.getInputStream());
00098         io.setOutputStream(socket.getOutputStream());
00099       }
00100       sendOpenConfirmation();
00101     }
00102     catch(Exception e){
00103       sendOpenFailure(SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
00104       close=true;
00105       disconnect();
00106       return; 
00107     }
00108 
00109     thread=Thread.currentThread();
00110     Buffer buf=new Buffer(rmpsize);
00111     Packet packet=new Packet(buf);
00112     int i=0;
00113     try{
00114       while(thread!=null && 
00115             io!=null && 
00116             io.in!=null){
00117         i=io.in.read(buf.buffer, 
00118                      14, 
00119                      buf.buffer.length-14
00120                      -Session.buffer_margin
00121                      );
00122         if(i<=0){
00123           eof();
00124           break;
00125         }
00126         packet.reset();
00127         if(close)break;
00128         buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
00129         buf.putInt(recipient);
00130         buf.putInt(i);
00131         buf.skip(i);
00132         getSession().write(packet, this, i);
00133       }
00134     }
00135     catch(Exception e){
00136       //System.err.println(e);
00137     }
00138     //thread=null;
00139     //eof();
00140     disconnect();
00141   }
00142 
00143   void getData(Buffer buf){
00144     setRecipient(buf.getInt());
00145     setRemoteWindowSize(buf.getUInt());
00146     setRemotePacketSize(buf.getInt());
00147     byte[] addr=buf.getString();
00148     int port=buf.getInt();
00149     byte[] orgaddr=buf.getString();
00150     int orgport=buf.getInt();
00151 
00152     /*
00153     System.err.println("addr: "+Util.byte2str(addr));
00154     System.err.println("port: "+port);
00155     System.err.println("orgaddr: "+Util.byte2str(orgaddr));
00156     System.err.println("orgport: "+orgport);
00157     */
00158 
00159     Session _session=null;
00160     try{
00161       _session=getSession();
00162     }
00163     catch(JSchException e){
00164       // session has been already down.
00165     }
00166 
00167     synchronized(pool){
00168       for(int i=0; i<pool.size(); i++){
00169         Object[] foo=(Object[])(pool.elementAt(i));
00170         if(foo[0]!=_session) continue;
00171         if(((Integer)foo[1]).intValue()!=port) continue;
00172         this.rport=port;
00173         this.target=(String)foo[2];
00174         if(foo[3]==null || (foo[3] instanceof Object[])){ this.lport=-1; }
00175         else{ this.lport=((Integer)foo[3]).intValue(); }
00176         if(foo.length>=6){
00177           this.factory=((SocketFactory)foo[5]);
00178         }
00179         break;
00180       }
00181       if(target==null){
00182         //System.err.println("??");
00183       }
00184     }
00185   }
00186 
00187   static Object[] getPort(Session session, int rport){
00188     synchronized(pool){
00189       for(int i=0; i<pool.size(); i++){
00190         Object[] bar=(Object[])(pool.elementAt(i));
00191         if(bar[0]!=session) continue;
00192         if(((Integer)bar[1]).intValue()!=rport) continue;
00193         return bar;
00194       }
00195       return null;
00196     }
00197   }
00198 
00199   static String[] getPortForwarding(Session session){
00200     java.util.Vector foo=new java.util.Vector();
00201     synchronized(pool){
00202       for(int i=0; i<pool.size(); i++){
00203         Object[] bar=(Object[])(pool.elementAt(i));
00204         if(bar[0]!=session) continue;
00205         if(bar[3]==null){ foo.addElement(bar[1]+":"+bar[2]+":"); }
00206         else{ foo.addElement(bar[1]+":"+bar[2]+":"+bar[3]); }
00207       }
00208     }
00209     String[] bar=new String[foo.size()];
00210     for(int i=0; i<foo.size(); i++){
00211       bar[i]=(String)(foo.elementAt(i));
00212     }
00213     return bar;
00214   }
00215 
00216   static String normalize(String address){
00217     if(address==null){ return "localhost"; }
00218     else if(address.length()==0 || address.equals("*")){ return ""; }
00219     else{ return address; }
00220   }
00221 
00222   static void addPort(Session session, String _address_to_bind, int port, String target, int lport, SocketFactory factory) throws JSchException{
00223     String address_to_bind=normalize(_address_to_bind);
00224     synchronized(pool){
00225       if(getPort(session, port)!=null){
00226         throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
00227       }
00228       Object[] foo=new Object[6];
00229       foo[0]=session; foo[1]=new Integer(port);
00230       foo[2]=target; foo[3]=new Integer(lport);
00231       foo[4]=address_to_bind;
00232       foo[5]=factory;
00233       pool.addElement(foo);
00234     }
00235   }
00236   static void addPort(Session session, String _address_to_bind, int port, String daemon, Object[] arg) throws JSchException{
00237     String address_to_bind=normalize(_address_to_bind);
00238     synchronized(pool){
00239       if(getPort(session, port)!=null){
00240         throw new JSchException("PortForwardingR: remote port "+port+" is already registered.");
00241       }
00242       Object[] foo=new Object[5];
00243       foo[0]=session; foo[1]=new Integer(port);
00244       foo[2]=daemon; foo[3]=arg;
00245       foo[4]=address_to_bind; 
00246       pool.addElement(foo);
00247     }
00248   }
00249   static void delPort(ChannelForwardedTCPIP c){
00250     Session _session=null;
00251     try{
00252       _session=c.getSession();
00253     }
00254     catch(JSchException e){
00255       // session has been already down.
00256     }
00257     if(_session!=null)
00258       delPort(_session, c.rport);
00259   }
00260   static void delPort(Session session, int rport){
00261     delPort(session, null, rport);
00262   }
00263   static void delPort(Session session, String address_to_bind, int rport){
00264     synchronized(pool){
00265       Object[] foo=null;
00266       for(int i=0; i<pool.size(); i++){
00267         Object[] bar=(Object[])(pool.elementAt(i));
00268         if(bar[0]!=session) continue;
00269         if(((Integer)bar[1]).intValue()!=rport) continue;
00270         foo=bar;
00271         break;
00272       }
00273       if(foo==null)return;
00274       pool.removeElement(foo);
00275       if(address_to_bind==null){
00276         address_to_bind=(String)foo[4];
00277       } 
00278       if(address_to_bind==null){
00279         address_to_bind="0.0.0.0";
00280       }
00281     }
00282 
00283     Buffer buf=new Buffer(100); // ??
00284     Packet packet=new Packet(buf);
00285 
00286     try{
00287       // byte SSH_MSG_GLOBAL_REQUEST 80
00288       // string "cancel-tcpip-forward"
00289       // boolean want_reply
00290       // string  address_to_bind (e.g. "127.0.0.1")
00291       // uint32  port number to bind
00292       packet.reset();
00293       buf.putByte((byte) 80/*SSH_MSG_GLOBAL_REQUEST*/);
00294       buf.putString(Util.str2byte("cancel-tcpip-forward"));
00295       buf.putByte((byte)0);
00296       buf.putString(Util.str2byte(address_to_bind));
00297       buf.putInt(rport);
00298       session.write(packet);
00299     }
00300     catch(Exception e){
00301 //    throw new JSchException(e.toString());
00302     }
00303   }
00304   static void delPort(Session session){
00305     int[] rport=null;
00306     int count=0;
00307     synchronized(pool){
00308       rport=new int[pool.size()];
00309       for(int i=0; i<pool.size(); i++){
00310         Object[] bar=(Object[])(pool.elementAt(i));
00311         if(bar[0]==session) {
00312           rport[count++]=((Integer)bar[1]).intValue();
00313         }
00314       }
00315     }
00316     for(int i=0; i<count; i++){
00317       delPort(session, rport[i]);
00318     }
00319   }
00320 
00325   public int getRemotePort(){return rport;}
00326   void setSocketFactory(SocketFactory factory){
00327     this.factory=factory;
00328   }
00329 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1