Session.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.io.*;
00033 import java.net.*;
00034 
00046 public class Session
00047 implements Runnable
00048 {
00049     static private final String version="JSCH-0.1.45";
00050 
00051     // http://ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-01.txt
00052     // permanent URI: http://tools.ietf.org/html/rfc4250
00053     static final int SSH_MSG_DISCONNECT=                      1;
00054     static final int SSH_MSG_IGNORE=                          2;
00055     static final int SSH_MSG_UNIMPLEMENTED=                   3;
00056     static final int SSH_MSG_DEBUG=                           4;
00057     static final int SSH_MSG_SERVICE_REQUEST=                 5;
00058     static final int SSH_MSG_SERVICE_ACCEPT=                  6;
00059     static final int SSH_MSG_KEXINIT=                        20;
00060     static final int SSH_MSG_NEWKEYS=                        21;
00061     static final int SSH_MSG_KEXDH_INIT=                     30;
00062     static final int SSH_MSG_KEXDH_REPLY=                    31;
00063     static final int SSH_MSG_KEX_DH_GEX_GROUP=               31;
00064     static final int SSH_MSG_KEX_DH_GEX_INIT=                32;
00065     static final int SSH_MSG_KEX_DH_GEX_REPLY=               33;
00066     static final int SSH_MSG_KEX_DH_GEX_REQUEST=             34;
00067     static final int SSH_MSG_GLOBAL_REQUEST=                 80;
00068     static final int SSH_MSG_REQUEST_SUCCESS=                81;
00069     static final int SSH_MSG_REQUEST_FAILURE=                82;
00070     static final int SSH_MSG_CHANNEL_OPEN=                   90;
00071     static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION=      91;
00072     static final int SSH_MSG_CHANNEL_OPEN_FAILURE=           92;
00073     static final int SSH_MSG_CHANNEL_WINDOW_ADJUST=          93;
00074     static final int SSH_MSG_CHANNEL_DATA=                   94;
00075     static final int SSH_MSG_CHANNEL_EXTENDED_DATA=          95;
00076     static final int SSH_MSG_CHANNEL_EOF=                    96;
00077     static final int SSH_MSG_CHANNEL_CLOSE=                  97;
00078     static final int SSH_MSG_CHANNEL_REQUEST=                98;
00079     static final int SSH_MSG_CHANNEL_SUCCESS=                99;
00080     static final int SSH_MSG_CHANNEL_FAILURE=               100;
00081 
00082     private static final int PACKET_MAX_SIZE = 256 * 1024;
00083 
00084     private byte[] V_S;                                 // server version
00085     private byte[] V_C=Util.str2byte("SSH-2.0-"+version); // client version
00086 
00087     private byte[] I_C; // the payload of the client's SSH_MSG_KEXINIT
00088     private byte[] I_S; // the payload of the server's SSH_MSG_KEXINIT
00089     private byte[] K_S; // the host key
00090 
00091     private byte[] session_id;
00092 
00093     private byte[] IVc2s;
00094     private byte[] IVs2c;
00095     private byte[] Ec2s;
00096     private byte[] Es2c;
00097     private byte[] MACc2s;
00098     private byte[] MACs2c;
00099 
00100     private int seqi=0;
00101     private int seqo=0;
00102 
00103     String[] guess=null;
00104     private Cipher s2ccipher;
00105     private Cipher c2scipher;
00106     private MAC s2cmac;
00107     private MAC c2smac;
00108     //private byte[] mac_buf;
00109     private byte[] s2cmac_result1;
00110     private byte[] s2cmac_result2;
00111 
00112     private Compression deflater;
00113     private Compression inflater;
00114 
00115     private IO io;
00116     private Socket socket;
00117     private int timeout=0;
00118 
00119     private volatile boolean isConnected=false;
00120 
00121     private boolean isAuthed=false;
00122 
00123     private Thread connectThread=null;
00124     private Object lock=new Object();
00125 
00126     boolean x11_forwarding=false;
00127     boolean agent_forwarding=false;
00128 
00129     InputStream in=null;
00130     OutputStream out=null;
00131 
00132     static Random random;
00133 
00134     Buffer buf;
00135     Packet packet;
00136 
00137     SocketFactory socket_factory=null;
00138 
00139     static final int buffer_margin = 32 + // maximum padding length
00140             20 + // maximum mac length
00141             32;  // margin for deflater; deflater may inflate data
00142 
00143     private java.util.Hashtable config=null;
00144 
00145     private Proxy proxy=null;
00146     private UserInfo userinfo;
00147 
00148     private String hostKeyAlias=null;
00149     private int serverAliveInterval=0;
00150     private int serverAliveCountMax=1;
00151 
00152     protected boolean daemon_thread=false;
00153 
00154     private long kex_start_time=0L;
00155 
00156     String host="127.0.0.1";
00157     int port=22;
00158 
00159     String username=null;
00160     byte[] password=null;
00161 
00162     JSch jsch;
00163 
00167     Session(JSch jsch) throws JSchException{
00168         super();
00169         this.jsch=jsch;
00170         buf=new Buffer();
00171         packet=new Packet(buf);
00172     }
00173 
00179     public void connect() throws JSchException{
00180         connect(timeout);
00181     }
00182 
00189     public void connect(int connectTimeout) throws JSchException{
00190         if(isConnected){
00191             throw new JSchException("session is already connected");
00192         }
00193 
00194         io=new IO();
00195         if(random==null){
00196             try{
00197                 Class c=Class.forName(getConfig("random"));
00198                 random=(Random)(c.newInstance());
00199             }
00200             catch(Exception e){ 
00201                 throw new JSchException(e.toString(), e);
00202             }
00203         }
00204         Packet.setRandom(random);
00205 
00206         if(JSch.getLogger().isEnabled(Logger.INFO)){
00207             JSch.getLogger().log(Logger.INFO, 
00208                     "Connecting to "+host+" port "+port);
00209         }
00210 
00211         try {
00212             int i, j;
00213 
00214             if(proxy==null){
00215                 InputStream in;
00216                 OutputStream out;
00217                 if(socket_factory==null){
00218                     socket=Util.createSocket(host, port, connectTimeout);
00219                     in=socket.getInputStream();
00220                     out=socket.getOutputStream();
00221                 }
00222                 else{
00223                     socket=socket_factory.createSocket(host, port);
00224                     in=socket_factory.getInputStream(socket);
00225                     out=socket_factory.getOutputStream(socket);
00226                 }
00227                 //if(timeout>0){ socket.setSoTimeout(timeout); }
00228                 socket.setTcpNoDelay(true);
00229                 io.setInputStream(in);
00230                 io.setOutputStream(out);
00231             }
00232             else{
00233                 synchronized(proxy){
00234                     proxy.connect(socket_factory, host, port, connectTimeout);
00235                     io.setInputStream(proxy.getInputStream());
00236                     io.setOutputStream(proxy.getOutputStream());
00237                     socket=proxy.getSocket();
00238                 }
00239             }
00240 
00241             if(connectTimeout>0 && socket!=null){
00242                 socket.setSoTimeout(connectTimeout);
00243             }
00244 
00245             isConnected=true;
00246 
00247             if(JSch.getLogger().isEnabled(Logger.INFO)){
00248                 JSch.getLogger().log(Logger.INFO, 
00249                         "Connection established");
00250             }
00251 
00252             jsch.addSession(this);
00253 
00254             {
00255                 // Some Cisco devices will miss to read '\n' if it is sent separately.
00256                 byte[] foo=new byte[V_C.length+1];
00257                 System.arraycopy(V_C, 0, foo, 0, V_C.length);
00258                 foo[foo.length-1]=(byte)'\n';
00259                 io.put(foo, 0, foo.length);
00260             }
00261 
00262             while(true){
00263                 i=0;
00264                 j=0;
00265                 while(i<buf.buffer.length){
00266                     j=io.getByte();
00267                     if(j<0)break;
00268                     buf.buffer[i]=(byte)j; i++; 
00269                     if(j==10)break;
00270                 }
00271                 if(j<0){
00272                     throw new JSchException("connection is closed by foreign host");
00273                 }
00274 
00275                 if(buf.buffer[i-1]==10){    // 0x0a
00276                     i--;
00277                     if(i>0 && buf.buffer[i-1]==13){  // 0x0d
00278                         i--;
00279                     }
00280                 }
00281 
00282                 if(i<=3 || 
00283                         ((i!=buf.buffer.length) &&
00284                                 (buf.buffer[0]!='S'||buf.buffer[1]!='S'||
00285                                 buf.buffer[2]!='H'||buf.buffer[3]!='-'))){
00286                     // It must not start with 'SSH-'
00287                     //System.err.println(new String(buf.buffer, 0, i);
00288                     continue;
00289                 }
00290 
00291                 if(i==buf.buffer.length ||
00292                         i<7 ||                                      // SSH-1.99 or SSH-2.0
00293                         (buf.buffer[4]=='1' && buf.buffer[6]!='9')  // SSH-1.5
00294                         ){
00295                     throw new JSchException("invalid server's version string");
00296                 }
00297                 break;
00298             }
00299 
00300             V_S=new byte[i]; System.arraycopy(buf.buffer, 0, V_S, 0, i);
00301             //System.err.println("V_S: ("+i+") ["+new String(V_S)+"]");
00302 
00303             if(JSch.getLogger().isEnabled(Logger.INFO)){
00304                 JSch.getLogger().log(Logger.INFO, 
00305                         "Remote version string: "+Util.byte2str(V_S));
00306                 JSch.getLogger().log(Logger.INFO, 
00307                         "Local version string: "+Util.byte2str(V_C));
00308             }
00309 
00310             send_kexinit();
00311 
00312             buf=read(buf);
00313             if(buf.getCommand()!=SSH_MSG_KEXINIT){
00314                 in_kex=false;
00315                 throw new JSchException("invalid protocol: "+buf.getCommand());
00316             }
00317 
00318             if(JSch.getLogger().isEnabled(Logger.INFO)){
00319                 JSch.getLogger().log(Logger.INFO, 
00320                         "SSH_MSG_KEXINIT received");
00321             }
00322 
00323             KeyExchange kex=receive_kexinit(buf);
00324 
00325             while(true){
00326                 buf=read(buf);
00327                 if(kex.getState()==buf.getCommand()){
00328                     kex_start_time=System.currentTimeMillis();
00329                     boolean result=kex.next(buf);
00330                     if(!result){
00331                         //System.err.println("verify: "+result);
00332                         in_kex=false;
00333                         throw new JSchException("verify: "+result);
00334                     }
00335                 }
00336                 else{
00337                     in_kex=false;
00338                     throw new JSchException("invalid protocol(kex): "+buf.getCommand());
00339                 }
00340                 if(kex.getState()==KeyExchange.STATE_END){
00341                     break;
00342                 }
00343             }
00344 
00345             try{ checkHost(host, port, kex); }
00346             catch(JSchException ee){
00347                 in_kex=false;
00348                 throw ee;
00349             }
00350 
00351             send_newkeys();
00352 
00353             // receive SSH_MSG_NEWKEYS(21)
00354             buf=read(buf);
00355             //System.err.println("read: 21 ? "+buf.getCommand());
00356             if(buf.getCommand()==SSH_MSG_NEWKEYS){
00357 
00358                 if(JSch.getLogger().isEnabled(Logger.INFO)){
00359                     JSch.getLogger().log(Logger.INFO, 
00360                             "SSH_MSG_NEWKEYS received");
00361                 }
00362 
00363                 receive_newkeys(buf, kex);
00364             }
00365             else{
00366                 in_kex=false;
00367                 throw new JSchException("invalid protocol(newkyes): "+buf.getCommand());
00368             }
00369 
00370             boolean auth=false;
00371             boolean auth_cancel=false;
00372 
00373             UserAuth ua=null;
00374             try{
00375                 Class c=Class.forName(getConfig("userauth.none"));
00376                 ua=(UserAuth)(c.newInstance());
00377             }
00378             catch(Exception e){ 
00379                 throw new JSchException(e.toString(), e);
00380             }
00381 
00382             auth=ua.start(this);
00383 
00384             String cmethods=getConfig("PreferredAuthentications");
00385 
00386             String[] cmethoda=Util.split(cmethods, ",");
00387 
00388             String smethods=null;
00389             if(!auth){
00390                 smethods=((UserAuthNone)ua).getMethods();
00391                 if(smethods!=null){
00392                     smethods=smethods.toLowerCase();
00393                 }
00394                 else{
00395                     // methods: publickey,password,keyboard-interactive
00396                     //smethods="publickey,password,keyboard-interactive";
00397                     smethods=cmethods;
00398                 }
00399             }
00400 
00401             String[] smethoda=Util.split(smethods, ",");
00402 
00403             int methodi=0;
00404 
00405             loop:
00406                 while(true){
00407 
00408                     while(!auth && 
00409                             cmethoda!=null && methodi<cmethoda.length){
00410 
00411                         String method=cmethoda[methodi++];
00412                         boolean acceptable=false;
00413                         for(int k=0; k<smethoda.length; k++){
00414                             if(smethoda[k].equals(method)){
00415                                 acceptable=true;
00416                                 break;
00417                             }
00418                         }
00419                         if(!acceptable){
00420                             continue;
00421                         }
00422 
00423                         //System.err.println("  method: "+method);
00424 
00425                         if(JSch.getLogger().isEnabled(Logger.INFO)){
00426                             String str="Authentications that can continue: ";
00427                             for(int k=methodi-1; k<cmethoda.length; k++){
00428                                 str+=cmethoda[k];
00429                                 if(k+1<cmethoda.length)
00430                                     str+=",";
00431                             }
00432                             JSch.getLogger().log(Logger.INFO, 
00433                                     str);
00434                             JSch.getLogger().log(Logger.INFO, 
00435                                     "Next authentication method: "+method);
00436                         }
00437 
00438                         ua=null;
00439                         try{
00440                             Class c=null;
00441                             if(getConfig("userauth."+method)!=null){
00442                                 c=Class.forName(getConfig("userauth."+method));
00443                                 ua=(UserAuth)(c.newInstance());
00444                             }
00445                         }
00446                         catch(Exception e){
00447                             if(JSch.getLogger().isEnabled(Logger.WARN)){
00448                                 JSch.getLogger().log(Logger.WARN, 
00449                                         "failed to load "+method+" method");
00450                             }
00451                         }
00452 
00453                         if(ua!=null){
00454                             auth_cancel=false;
00455                             try{ 
00456                                 auth=ua.start(this); 
00457                                 if(auth && 
00458                                         JSch.getLogger().isEnabled(Logger.INFO)){
00459                                     JSch.getLogger().log(Logger.INFO, 
00460                                             "Authentication succeeded ("+method+").");
00461                                 }
00462                             }
00463                             catch(JSchAuthCancelException ee){
00464                                 auth_cancel=true;
00465                             }
00466                             catch(JSchPartialAuthException ee){
00467                                 String tmp = smethods;
00468                                 smethods=ee.getMethods();
00469                                 smethoda=Util.split(smethods, ",");
00470                                 if(!tmp.equals(smethods)){
00471                                     methodi=0;
00472                                 }
00473                                 //System.err.println("PartialAuth: "+methods);
00474                                 auth_cancel=false;
00475                                 continue loop;
00476                             }
00477                             catch(RuntimeException ee){
00478                                 throw ee;
00479                             }
00480                             catch(Exception ee){
00481                                 //System.err.println("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures
00482                                 break loop;
00483                             }
00484                         }
00485                     }
00486                     break;
00487                 }
00488 
00489             if(!auth){
00490                 if(auth_cancel)
00491                     throw new JSchException("Auth cancel");
00492                 throw new JSchException("Auth fail");
00493             }
00494 
00495             if(connectTimeout>0 || timeout>0){
00496                 socket.setSoTimeout(timeout);
00497             }
00498 
00499             isAuthed=true;
00500 
00501             synchronized(lock){
00502                 if(isConnected){
00503                     connectThread=new Thread(this);
00504                     connectThread.setName("Connect thread "+host+" session");
00505                     if(daemon_thread){
00506                         connectThread.setDaemon(daemon_thread);
00507                     }
00508                     connectThread.start();
00509                 }
00510                 else{
00511                     // The session has been already down and
00512                     // we don't have to start new thread.
00513                 }
00514             }
00515         }
00516         catch(Exception e) {
00517             in_kex=false;
00518             if(isConnected){
00519                 try{
00520                     packet.reset();
00521                     buf.putByte((byte)SSH_MSG_DISCONNECT);
00522                     buf.putInt(3);
00523                     buf.putString(Util.str2byte(e.toString()));
00524                     buf.putString(Util.str2byte("en"));
00525                     write(packet);
00526                     disconnect();
00527                 }
00528                 catch(Exception ee){
00529                 }
00530             }
00531             isConnected=false;
00532             //e.printStackTrace();
00533             if(e instanceof RuntimeException) throw (RuntimeException)e;
00534             if(e instanceof JSchException) throw (JSchException)e;
00535             throw new JSchException("Session.connect: "+e);
00536         }
00537         finally{
00538             Util.bzero(this.password);
00539             this.password=null;
00540         }
00541     }
00542 
00547     private KeyExchange receive_kexinit(Buffer buf) throws Exception {
00548         int j=buf.getInt();
00549         if(j!=buf.getLength()){    // packet was compressed and
00550             buf.getByte();           // j is the size of deflated packet.
00551             I_S=new byte[buf.index-5];
00552         }
00553         else{
00554             I_S=new byte[j-1-buf.getByte()];
00555         }
00556         System.arraycopy(buf.buffer, buf.s, I_S, 0, I_S.length);
00557 
00558         if(!in_kex){     // We are in rekeying activated by the remote!
00559             send_kexinit();
00560         }
00561 
00562         guess=KeyExchange.guess(I_S, I_C);
00563         if(guess==null){
00564             throw new JSchException("Algorithm negotiation fail");
00565         }
00566 
00567         if(!isAuthed &&
00568                 (guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS].equals("none") ||
00569                         (guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC].equals("none")))){
00570             throw new JSchException("NONE Cipher should not be chosen before authentification is successed.");
00571         }
00572 
00573         KeyExchange kex=null;
00574         try{
00575             Class c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_KEX_ALGS]));
00576             kex=(KeyExchange)(c.newInstance());
00577         }
00578         catch(Exception e){ 
00579             throw new JSchException(e.toString(), e);
00580         }
00581 
00582         kex.init(this, V_S, V_C, I_S, I_C);
00583         return kex;
00584     }
00585 
00586     private boolean in_kex=false;
00587 
00593     public void rekey() throws Exception {
00594         send_kexinit();
00595     }
00596     private void send_kexinit() throws Exception {
00597         if(in_kex)
00598             return;
00599 
00600         String cipherc2s=getConfig("cipher.c2s");
00601         String ciphers2c=getConfig("cipher.s2c");
00602 
00603         String[] not_available_ciphers=checkCiphers(getConfig("CheckCiphers"));
00604         if(not_available_ciphers!=null && not_available_ciphers.length>0){
00605             cipherc2s=Util.diffString(cipherc2s, not_available_ciphers);
00606             ciphers2c=Util.diffString(ciphers2c, not_available_ciphers);
00607             if(cipherc2s==null || ciphers2c==null){
00608                 throw new JSchException("There are not any available ciphers.");
00609             }
00610         }
00611 
00612         String kex=getConfig("kex");
00613         String[] not_available_kexes=checkKexes(getConfig("CheckKexes"));
00614         if(not_available_kexes!=null && not_available_kexes.length>0){
00615             kex=Util.diffString(kex, not_available_kexes);
00616             if(kex==null){
00617                 throw new JSchException("There are not any available kexes.");
00618             }
00619         }
00620 
00621         in_kex=true;
00622         kex_start_time=System.currentTimeMillis();
00623 
00624         // byte      SSH_MSG_KEXINIT(20)
00625         // byte[16]  cookie (random bytes)
00626         // string    kex_algorithms
00627         // string    server_host_key_algorithms
00628         // string    encryption_algorithms_client_to_server
00629         // string    encryption_algorithms_server_to_client
00630         // string    mac_algorithms_client_to_server
00631         // string    mac_algorithms_server_to_client
00632         // string    compression_algorithms_client_to_server
00633         // string    compression_algorithms_server_to_client
00634         // string    languages_client_to_server
00635         // string    languages_server_to_client
00636         Buffer buf = new Buffer();                // send_kexinit may be invoked
00637         Packet packet = new Packet(buf);          // by user thread.
00638         packet.reset();
00639         buf.putByte((byte) SSH_MSG_KEXINIT);
00640         synchronized(random){
00641             random.fill(buf.buffer, buf.index, 16); buf.skip(16);
00642         }
00643         buf.putString(Util.str2byte(kex));
00644         buf.putString(Util.str2byte(getConfig("server_host_key")));
00645         buf.putString(Util.str2byte(cipherc2s));
00646         buf.putString(Util.str2byte(ciphers2c));
00647         buf.putString(Util.str2byte(getConfig("mac.c2s")));
00648         buf.putString(Util.str2byte(getConfig("mac.s2c")));
00649         buf.putString(Util.str2byte(getConfig("compression.c2s")));
00650         buf.putString(Util.str2byte(getConfig("compression.s2c")));
00651         buf.putString(Util.str2byte(getConfig("lang.c2s")));
00652         buf.putString(Util.str2byte(getConfig("lang.s2c")));
00653         buf.putByte((byte)0);
00654         buf.putInt(0);
00655 
00656         buf.setOffSet(5);
00657         I_C=new byte[buf.getLength()];
00658         buf.getByte(I_C);
00659 
00660         write(packet);
00661 
00662         if(JSch.getLogger().isEnabled(Logger.INFO)){
00663             JSch.getLogger().log(Logger.INFO, 
00664                     "SSH_MSG_KEXINIT sent");
00665         }
00666     }
00667 
00668     private void send_newkeys() throws Exception {
00669         // send SSH_MSG_NEWKEYS(21)
00670         packet.reset();
00671         buf.putByte((byte)SSH_MSG_NEWKEYS);
00672         write(packet);
00673 
00674         if(JSch.getLogger().isEnabled(Logger.INFO)){
00675             JSch.getLogger().log(Logger.INFO, 
00676                     "SSH_MSG_NEWKEYS sent");
00677         }
00678     }
00679 
00680     private void checkHost(String chost, int port, KeyExchange kex) throws JSchException {
00681         String shkc=getConfig("StrictHostKeyChecking");
00682 
00683         if(hostKeyAlias!=null){
00684             chost=hostKeyAlias;
00685         }
00686 
00687         //System.err.println("shkc: "+shkc);
00688 
00689         byte[] K_S=kex.getHostKey();
00690         String key_type=kex.getKeyType();
00691         String key_fprint=kex.getFingerPrint();
00692 
00693         if(hostKeyAlias==null && port!=22){
00694             chost=("["+chost+"]:"+port);
00695         }
00696 
00697         //    hostkey=new HostKey(chost, K_S);
00698 
00699         HostKeyRepository hkr=jsch.getHostKeyRepository();
00700         int i=0;
00701         synchronized(hkr){
00702             i=hkr.check(chost, K_S);
00703         }
00704 
00705         boolean insert=false;
00706 
00707         if((shkc.equals("ask") || shkc.equals("yes")) &&
00708                 i==HostKeyRepository.CHANGED) {
00709             String file=null;
00710             synchronized(hkr){
00711                 file=hkr.getKnownHostsRepositoryID();
00712             }
00713             if(file==null){file="known_hosts";}
00714 
00715             boolean b=false;
00716 
00717             if(userinfo!=null){
00718                 String message=
00719                         "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!\n"+
00720                                 "IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\n"+
00721                                 "Someone could be eavesdropping on you right now (man-in-the-middle attack)!\n"+
00722                                 "It is also possible that the "+key_type+" host key has just been changed.\n"+
00723                                 "The fingerprint for the "+key_type+" key sent by the remote host is\n"+
00724                                 key_fprint+".\n"+
00725                                 "Please contact your system administrator.\n"+
00726                                 "Add correct host key in "+file+" to get rid of this message.";
00727 
00728                 if(shkc.equals("ask")){
00729                     b=userinfo.promptYesNo(message+
00730                             "\nDo you want to delete the old key and insert the new key?");
00731                 }
00732                 else{  // shkc.equals("yes")
00733                     userinfo.showMessage(message);
00734                 }
00735             }
00736 
00737             if(!b){
00738                 throw new JSchException("HostKey has been changed: "+chost);
00739             }
00740 
00741             synchronized(hkr){
00742                 hkr.remove(chost, 
00743                         (key_type.equals("DSA") ? "ssh-dss" : "ssh-rsa"), 
00744                         null);
00745                 insert=true;
00746             }
00747         }
00748 
00749         if((shkc.equals("ask") || shkc.equals("yes")) &&
00750                 (i!=HostKeyRepository.OK) && !insert){
00751             if(shkc.equals("yes")){
00752                 throw new JSchException("reject HostKey: "+host);
00753             }
00754             //System.err.println("finger-print: "+key_fprint);
00755             if(userinfo!=null){
00756                 boolean foo=userinfo.promptYesNo(
00757                         "The authenticity of host '"+host+"' can't be established.\n"+
00758                                 key_type+" key fingerprint is "+key_fprint+".\n"+
00759                                 "Are you sure you want to continue connecting?"
00760                         );
00761                 if(!foo){
00762                     throw new JSchException("reject HostKey: "+host);
00763                 }
00764                 insert=true;
00765             }
00766             else{
00767                 if(i==HostKeyRepository.NOT_INCLUDED) 
00768                     throw new JSchException("UnknownHostKey: "+host+". "+key_type+" key fingerprint is "+key_fprint);
00769                 else 
00770                     throw new JSchException("HostKey has been changed: "+host);
00771             }
00772         }
00773 
00774         if(shkc.equals("no") && 
00775                 HostKeyRepository.NOT_INCLUDED==i){
00776             insert=true;
00777         }
00778 
00779         if(i==HostKeyRepository.OK &&
00780                 JSch.getLogger().isEnabled(Logger.INFO)){
00781             JSch.getLogger().log(Logger.INFO, 
00782                     "Host '"+host+"' is known and mathces the "+key_type+" host key");
00783         }
00784 
00785         if(insert &&
00786                 JSch.getLogger().isEnabled(Logger.WARN)){
00787             JSch.getLogger().log(Logger.WARN, 
00788                     "Permanently added '"+host+"' ("+key_type+") to the list of known hosts.");
00789         }
00790 
00791         String hkh=getConfig("HashKnownHosts");
00792         if(hkh.equals("yes") && (hkr instanceof KnownHosts)){
00793             hostkey=((KnownHosts)hkr).createHashedHostKey(chost, K_S);
00794         }
00795         else{
00796             hostkey=new HostKey(chost, K_S);
00797         }
00798 
00799         if(insert){
00800             synchronized(hkr){
00801                 hkr.add(hostkey, userinfo);
00802             }
00803 
00804         }
00805 
00806     }
00807 
00808     //public void start(){ (new Thread(this)).start();  }
00809 
00810 
00833     public Channel openChannel(String type) throws JSchException{
00834         if(!isConnected){
00835             throw new JSchException("session is down");
00836         }
00837         try{
00838             Channel channel=Channel.getChannel(type);
00839             addChannel(channel);
00840             channel.init();
00841             return channel;
00842         }
00843         catch(Exception e){
00844             //e.printStackTrace();
00845         }
00846         return null;
00847     }
00848 
00852     // encode will bin invoked in write with synchronization.
00853     public void encode(Packet packet) throws Exception{
00854         //System.err.println("encode: "+packet.buffer.getCommand());
00855         //System.err.println("        "+packet.buffer.index);
00856         //if(packet.buffer.getCommand()==96){
00857         //Thread.dumpStack();
00858         //}
00859         if(deflater!=null){
00860             compress_len[0]=packet.buffer.index;
00861             packet.buffer.buffer=deflater.compress(packet.buffer.buffer, 
00862                     5, compress_len);
00863             packet.buffer.index=compress_len[0];
00864         }
00865         if(c2scipher!=null){
00866             //packet.padding(c2scipher.getIVSize());
00867             packet.padding(c2scipher_size);
00868             // doesn't packet.padding(...) already add random padding
00869             // to the packet? Why do we overwrite them again with
00870             // new random data?   -- P.E.
00871             int pad=packet.buffer.buffer[4];
00872             synchronized(random){
00873                 random.fill(packet.buffer.buffer, packet.buffer.index-pad, pad);
00874             }
00875         }
00876         else{
00877             packet.padding(8);
00878         }
00879 
00880         if(c2smac!=null){
00881             c2smac.update(seqo);
00882             c2smac.update(packet.buffer.buffer, 0, packet.buffer.index);
00883             c2smac.doFinal(packet.buffer.buffer, packet.buffer.index);
00884         }
00885         if(c2scipher!=null){
00886             byte[] buf=packet.buffer.buffer;
00887             c2scipher.update(buf, 0, packet.buffer.index, buf, 0);
00888         }
00889         if(c2smac!=null){
00890             packet.buffer.skip(c2smac.getBlockSize());
00891         }
00892     }
00893 
00894     int[] uncompress_len=new int[1];
00895     int[] compress_len=new int[1];
00896 
00897     private int s2ccipher_size=8;
00898     private int c2scipher_size=8;
00899 
00903     public Buffer read(Buffer buf) throws Exception{
00904         int j=0;
00905         while(true){
00906             buf.reset();
00907             io.getByte(buf.buffer, buf.index, s2ccipher_size); 
00908             buf.index+=s2ccipher_size;
00909             if(s2ccipher!=null){
00910                 s2ccipher.update(buf.buffer, 0, s2ccipher_size, buf.buffer, 0);
00911             }
00912             j=((buf.buffer[0]<<24)&0xff000000)|
00913                     ((buf.buffer[1]<<16)&0x00ff0000)|
00914                     ((buf.buffer[2]<< 8)&0x0000ff00)|
00915                     ((buf.buffer[3]    )&0x000000ff);
00916             // RFC 4253 6.1. Maximum Packet Length
00917             if(j<5 || j>PACKET_MAX_SIZE){
00918                 start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE);
00919             }
00920             int need = j+4-s2ccipher_size;
00921             //if(need<0){
00922             //  throw new IOException("invalid data");
00923             //}
00924             if((buf.index+need)>buf.buffer.length){
00925                 byte[] foo=new byte[buf.index+need];
00926                 System.arraycopy(buf.buffer, 0, foo, 0, buf.index);
00927                 buf.buffer=foo;
00928             }
00929 
00930             if((need%s2ccipher_size)!=0){
00931                 String message="Bad packet length "+need;
00932                 if(JSch.getLogger().isEnabled(Logger.FATAL)){
00933                     JSch.getLogger().log(Logger.FATAL, message); 
00934                 }
00935                 start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-s2ccipher_size);
00936             }
00937 
00938             if(need>0){
00939                 io.getByte(buf.buffer, buf.index, need); buf.index+=(need);
00940                 if(s2ccipher!=null){
00941                     s2ccipher.update(buf.buffer, s2ccipher_size, need, buf.buffer, s2ccipher_size);
00942                 }
00943             }
00944 
00945             if(s2cmac!=null){
00946                 s2cmac.update(seqi);
00947                 s2cmac.update(buf.buffer, 0, buf.index);
00948 
00949                 s2cmac.doFinal(s2cmac_result1, 0);
00950                 io.getByte(s2cmac_result2, 0, s2cmac_result2.length);
00951                 if(!java.util.Arrays.equals(s2cmac_result1, s2cmac_result2)){
00952                     if(need > PACKET_MAX_SIZE){
00953                         throw new IOException("MAC Error");
00954                     }
00955                     start_discard(buf, s2ccipher, s2cmac, j, PACKET_MAX_SIZE-need);
00956                     continue;
00957                 }
00958             }
00959 
00960             seqi++;
00961 
00962             if(inflater!=null){
00963                 //inflater.uncompress(buf);
00964                 int pad=buf.buffer[4];
00965                 uncompress_len[0]=buf.index-5-pad;
00966                 byte[] foo=inflater.uncompress(buf.buffer, 5, uncompress_len);
00967                 if(foo!=null){
00968                     buf.buffer=foo;
00969                     buf.index=5+uncompress_len[0];
00970                 }
00971                 else{
00972                     System.err.println("fail in inflater");
00973                     break;
00974                 }
00975             }
00976 
00977             int type=buf.getCommand()&0xff;
00978             //System.err.println("read: "+type);
00979             if(type==SSH_MSG_DISCONNECT){
00980                 buf.rewind();
00981                 buf.getInt();buf.getShort();
00982                 int reason_code=buf.getInt();
00983                 byte[] description=buf.getString();
00984                 byte[] language_tag=buf.getString();
00985                 throw new JSchException("SSH_MSG_DISCONNECT: "+
00986                         reason_code+
00987                         " "+Util.byte2str(description)+
00988                         " "+Util.byte2str(language_tag));
00989                 //break;
00990             }
00991             else if(type==SSH_MSG_IGNORE){
00992             }
00993             else if(type==SSH_MSG_UNIMPLEMENTED){
00994                 buf.rewind();
00995                 buf.getInt();buf.getShort();
00996                 int reason_id=buf.getInt();
00997                 if(JSch.getLogger().isEnabled(Logger.INFO)){
00998                     JSch.getLogger().log(Logger.INFO, 
00999                             "Received SSH_MSG_UNIMPLEMENTED for "+reason_id);
01000                 }
01001             }
01002             else if(type==SSH_MSG_DEBUG){
01003                 buf.rewind();
01004                 buf.getInt();buf.getShort();
01005                 /*
01006     byte always_display=(byte)buf.getByte();
01007     byte[] message=buf.getString();
01008     byte[] language_tag=buf.getString();
01009     System.err.println("SSH_MSG_DEBUG:"+
01010                " "+Util.byte2str(message)+
01011                " "+Util.byte2str(language_tag));
01012                  */
01013             }
01014             else if(type==SSH_MSG_CHANNEL_WINDOW_ADJUST){
01015                 buf.rewind();
01016                 buf.getInt();buf.getShort();
01017                 Channel c=Channel.getChannel(buf.getInt(), this);
01018                 if(c==null){
01019                 }
01020                 else{
01021                     c.addRemoteWindowSize(buf.getInt()); 
01022                 }
01023             }
01024             else if(type==UserAuth.SSH_MSG_USERAUTH_SUCCESS){
01025                 isAuthed=true;
01026                 if(inflater==null && deflater==null){
01027                     String method;
01028                     method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS];
01029                     initDeflater(method);
01030                     method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC];
01031                     initInflater(method);
01032                 }
01033                 break;
01034             }
01035             else{
01036                 break;
01037             }
01038         }
01039         buf.rewind();
01040         return buf;
01041     }
01042 
01043     private void start_discard(Buffer buf, Cipher cipher, MAC mac, 
01044             int packet_length, int discard) throws JSchException, IOException{
01045         MAC discard_mac = null;
01046 
01047         if(!cipher.isCBC()){
01048             // this error message is not really useful here, is it?
01049             // how does it relate to the condition?  -- P.E.
01050             throw new JSchException("Packet corrupt");
01051         }
01052 
01053         if(packet_length!=PACKET_MAX_SIZE && mac != null){
01054             discard_mac = mac;
01055         }
01056 
01057         discard -= buf.index;
01058 
01059         while(discard>0){
01060             buf.reset();
01061             int len = discard>buf.buffer.length ? buf.buffer.length : discard;
01062             io.getByte(buf.buffer, 0, len);
01063             if(discard_mac!=null){
01064                 discard_mac.update(buf.buffer, 0, len);
01065             }
01066             discard -= len;
01067         }
01068 
01069         if(discard_mac!=null){
01070             discard_mac.doFinal(buf.buffer, 0);
01071         }
01072 
01073         throw new JSchException("Packet corrupt");
01074     }
01075 
01076     byte[] getSessionId(){
01077         return session_id;
01078     }
01079 
01080     private void receive_newkeys(Buffer buf, KeyExchange kex) throws Exception {
01081         updateKeys(kex);
01082         in_kex=false;
01083     }
01084     private void updateKeys(KeyExchange kex) throws Exception{
01085         byte[] K=kex.getK();
01086         byte[] H=kex.getH();
01087         HASH hash=kex.getHash();
01088 
01089         //    String[] guess=kex.guess;
01090 
01091         if(session_id==null){
01092             session_id=new byte[H.length];
01093             System.arraycopy(H, 0, session_id, 0, H.length);
01094         }
01095 
01096         /*
01097       Initial IV client to server:     HASH (K || H || "A" || session_id)
01098       Initial IV server to client:     HASH (K || H || "B" || session_id)
01099       Encryption key client to server: HASH (K || H || "C" || session_id)
01100       Encryption key server to client: HASH (K || H || "D" || session_id)
01101       Integrity key client to server:  HASH (K || H || "E" || session_id)
01102       Integrity key server to client:  HASH (K || H || "F" || session_id)
01103          */
01104 
01105         buf.reset();
01106         buf.putMPInt(K);
01107         buf.putByte(H);
01108         buf.putByte((byte)0x41);
01109         buf.putByte(session_id);
01110         hash.update(buf.buffer, 0, buf.index);
01111         IVc2s=hash.digest();
01112 
01113         int j=buf.index-session_id.length-1;
01114 
01115         buf.buffer[j]++;
01116         hash.update(buf.buffer, 0, buf.index);
01117         IVs2c=hash.digest();
01118 
01119         buf.buffer[j]++;
01120         hash.update(buf.buffer, 0, buf.index);
01121         Ec2s=hash.digest();
01122 
01123         buf.buffer[j]++;
01124         hash.update(buf.buffer, 0, buf.index);
01125         Es2c=hash.digest();
01126 
01127         buf.buffer[j]++;
01128         hash.update(buf.buffer, 0, buf.index);
01129         MACc2s=hash.digest();
01130 
01131         buf.buffer[j]++;
01132         hash.update(buf.buffer, 0, buf.index);
01133         MACs2c=hash.digest();
01134 
01135         try{
01136             Class c;
01137             String method;
01138 
01139             method=guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC];
01140             c=Class.forName(getConfig(method));
01141             s2ccipher=(Cipher)(c.newInstance());
01142             while(s2ccipher.getBlockSize()>Es2c.length){
01143                 buf.reset();
01144                 buf.putMPInt(K);
01145                 buf.putByte(H);
01146                 buf.putByte(Es2c);
01147                 hash.update(buf.buffer, 0, buf.index);
01148                 byte[] foo=hash.digest();
01149                 byte[] bar=new byte[Es2c.length+foo.length];
01150                 System.arraycopy(Es2c, 0, bar, 0, Es2c.length);
01151                 System.arraycopy(foo, 0, bar, Es2c.length, foo.length);
01152                 Es2c=bar;
01153             }
01154             s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c);
01155             s2ccipher_size=s2ccipher.getIVSize();
01156 
01157             method=guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC];
01158             c=Class.forName(getConfig(method));
01159             s2cmac=(MAC)(c.newInstance());
01160             s2cmac.init(MACs2c);
01161             //mac_buf=new byte[s2cmac.getBlockSize()];
01162             s2cmac_result1=new byte[s2cmac.getBlockSize()];
01163             s2cmac_result2=new byte[s2cmac.getBlockSize()];
01164 
01165             method=guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS];
01166             c=Class.forName(getConfig(method));
01167             c2scipher=(Cipher)(c.newInstance());
01168             while(c2scipher.getBlockSize()>Ec2s.length){
01169                 buf.reset();
01170                 buf.putMPInt(K);
01171                 buf.putByte(H);
01172                 buf.putByte(Ec2s);
01173                 hash.update(buf.buffer, 0, buf.index);
01174                 byte[] foo=hash.digest();
01175                 byte[] bar=new byte[Ec2s.length+foo.length];
01176                 System.arraycopy(Ec2s, 0, bar, 0, Ec2s.length);
01177                 System.arraycopy(foo, 0, bar, Ec2s.length, foo.length);
01178                 Ec2s=bar;
01179             }
01180             c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s);
01181             c2scipher_size=c2scipher.getIVSize();
01182 
01183             method=guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS];
01184             c=Class.forName(getConfig(method));
01185             c2smac=(MAC)(c.newInstance());
01186             c2smac.init(MACc2s);
01187 
01188             method=guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS];
01189             initDeflater(method);
01190 
01191             method=guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC];
01192             initInflater(method);
01193         }
01194         catch(Exception e){ 
01195             if(e instanceof JSchException)
01196                 throw e;
01197             throw new JSchException(e.toString(), e);
01198             //System.err.println("updatekeys: "+e); 
01199         }
01200     }
01201 
01202     /*public*/ /*synchronized*/ void write(Packet packet, Channel c, int length) throws Exception{
01203         long t = getTimeout();
01204         while(true){
01205             if(in_kex){
01206                 if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){
01207                     throw new JSchException("timeout in wating for rekeying process.");
01208                 }
01209                 try{Thread.sleep(10);}
01210                 catch(java.lang.InterruptedException e){};
01211                 continue;
01212             }
01213             synchronized(c){
01214 
01215                 if(c.rwsize<length){
01216                     try{ 
01217                         c.notifyme++;
01218                         c.wait(100); 
01219                     }
01220                     catch(java.lang.InterruptedException e){
01221                     }
01222                     finally{
01223                         c.notifyme--;
01224                     }
01225                 }
01226 
01227                 if(c.rwsize>=length){
01228                     c.rwsize-=length;
01229                     break;
01230                 }
01231 
01232             }
01233             if(c.close || !c.isConnected()){
01234                 throw new IOException("channel is broken");
01235             }
01236 
01237             boolean sendit=false;
01238             int s=0;
01239             byte command=0;
01240             int recipient=-1;
01241             synchronized(c){
01242                 if(c.rwsize>0){
01243                     long len=c.rwsize;
01244                     if(len>length){
01245                         len=length;
01246                     }
01247                     if(len!=length){
01248                         s=packet.shift((int)len, 
01249                                 (c2scipher!=null ? c2scipher_size : 8),
01250                                 (c2smac!=null ? c2smac.getBlockSize() : 0));
01251                     }
01252                     command=packet.buffer.getCommand();
01253                     recipient=c.getRecipient();
01254                     length-=len;
01255                     c.rwsize-=len;
01256                     sendit=true;
01257                 }
01258             }
01259             if(sendit){
01260                 _write(packet);
01261                 if(length==0){
01262                     return;
01263                 }
01264                 packet.unshift(command, recipient, s, length);
01265             }
01266 
01267             synchronized(c){
01268                 if(in_kex){
01269                     continue;
01270                 }
01271                 if(c.rwsize>=length){
01272                     c.rwsize-=length;
01273                     break;
01274                 }
01275 
01276                 //try{ 
01277                     //System.out.println("1wait: "+c.rwsize);
01278                     //  c.notifyme++;
01279                     //  c.wait(100); 
01280                 //}
01281                 //catch(java.lang.InterruptedException e){
01282                 //}
01283                 //finally{
01284                 //  c.notifyme--;
01285                 //}
01286             }
01287         }
01288         _write(packet);
01289     }
01290 
01294     public void write(Packet packet) throws Exception{
01295         // System.err.println("in_kex="+in_kex+" "+(packet.buffer.getCommand()));
01296         long t = getTimeout();
01297         while(in_kex){
01298             if(t>0L && (System.currentTimeMillis()-kex_start_time)>t){
01299                 throw new JSchException("timeout in wating for rekeying process.");
01300             }
01301             byte command=packet.buffer.getCommand();
01302             //System.err.println("command: "+command);
01303             if(command==SSH_MSG_KEXINIT ||
01304                     command==SSH_MSG_NEWKEYS ||
01305                     command==SSH_MSG_KEXDH_INIT ||
01306                     command==SSH_MSG_KEXDH_REPLY ||
01307                     command==SSH_MSG_KEX_DH_GEX_GROUP ||
01308                     command==SSH_MSG_KEX_DH_GEX_INIT ||
01309                     command==SSH_MSG_KEX_DH_GEX_REPLY ||
01310                     command==SSH_MSG_KEX_DH_GEX_REQUEST ||
01311                     command==SSH_MSG_DISCONNECT){
01312                 break;
01313             }
01314             try{Thread.sleep(10);}
01315             catch(java.lang.InterruptedException e){};
01316         }
01317         _write(packet);
01318     }
01319 
01320     private void _write(Packet packet) throws Exception{
01321         synchronized(lock){
01322             encode(packet);
01323             if(io!=null){
01324                 io.put(packet);
01325                 seqo++;
01326             }
01327         }
01328     }
01329 
01330     Runnable thread;
01336     public void run(){
01337         thread=this;
01338 
01339         byte[] foo;
01340         Buffer buf=new Buffer();
01341         Packet packet=new Packet(buf);
01342         int i=0;
01343         Channel channel;
01344         int[] start=new int[1];
01345         int[] length=new int[1];
01346         KeyExchange kex=null;
01347 
01348         int stimeout=0;
01349         try{
01350             while(isConnected &&
01351                     thread!=null){
01352                 try{
01353                     buf=read(buf);
01354                     stimeout=0;
01355                 }
01356                 catch(InterruptedIOException/*SocketTimeoutException*/ ee){
01357                     if(!in_kex && stimeout<serverAliveCountMax){
01358                         sendKeepAliveMsg();
01359                         stimeout++;
01360                         continue;
01361                     }
01362                     else if(in_kex && stimeout<serverAliveCountMax){
01363                         stimeout++;
01364                         continue;
01365                     }
01366                     throw ee;
01367                 }
01368 
01369                 int msgType=buf.getCommand()&0xff;
01370 
01371                 if(kex!=null && kex.getState()==msgType){
01372                     kex_start_time=System.currentTimeMillis();
01373                     boolean result=kex.next(buf);
01374                     if(!result){
01375                         throw new JSchException("verify: "+result);
01376                     }
01377                     continue;
01378                 }
01379 
01380                 if(jsch.getLogger().isEnabled(Logger.DEBUG)) {
01381                     jsch.getLogger().log(Logger.DEBUG, "packet received, type: " +
01382                             msgType);
01383                 }
01384 
01385 
01386                 switch(msgType){
01387                 case SSH_MSG_KEXINIT:
01388                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01389                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_KEXINIT received");
01390                     }
01391                     //System.err.println("KEXINIT");
01392                     kex=receive_kexinit(buf);
01393                     break;
01394 
01395                 case SSH_MSG_NEWKEYS:
01396                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01397                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_NEWKEYS received");
01398                     }
01399                     //System.err.println("NEWKEYS");
01400                     send_newkeys();
01401                     receive_newkeys(buf, kex);
01402                     kex=null;
01403                     break;
01404 
01405                 case SSH_MSG_CHANNEL_DATA:
01406                     buf.getInt(); 
01407                     buf.getByte(); 
01408                     buf.getByte(); 
01409                     i=buf.getInt(); 
01410                     channel=Channel.getChannel(i, this);
01411                     foo=buf.getString(start, length);
01412                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01413                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_DATA received, channel: "+i + ", len: " + length[0]);
01414                     }
01415                     if(channel==null){
01416                         break;
01417                     }
01418 
01419                     if(length[0]==0){
01420                         break;
01421                     }
01422 
01423                     try{
01424                         channel.write(foo, start[0], length[0]);
01425                     }
01426                     catch(Exception e){
01427                         //System.err.println(e);
01428                         try{channel.disconnect();}catch(Exception ee){}
01429                         break;
01430                     }
01431                     int len=length[0];
01432                     channel.setLocalWindowSize(channel.lwsize-len);
01433                     if(channel.lwsize<channel.lwsize_max/2){
01434                         packet.reset();
01435                         buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST);
01436                         buf.putInt(channel.getRecipient());
01437                         buf.putInt(channel.lwsize_max-channel.lwsize);
01438                         write(packet);
01439                         channel.setLocalWindowSize(channel.lwsize_max);
01440                     }
01441                     break;
01442 
01443                 case SSH_MSG_CHANNEL_EXTENDED_DATA:
01444                     buf.getInt();
01445                     buf.getShort();
01446                     i=buf.getInt();
01447                     channel=Channel.getChannel(i, this);
01448                     int type_code = buf.getInt();                   // data_type_code == 1
01449                     foo=buf.getString(start, length);
01450                     //System.err.println("stderr: "+new String(foo,start[0],length[0]));
01451                     if(channel==null){
01452                         break;
01453                     }
01454 
01455                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01456                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL__EXTENDED_DATA received, channel: "+i + ", len: " + length[0] +", type: " + type_code);
01457                     }
01458 
01459                     if(length[0]==0){
01460                         break;
01461                     }
01462 
01463                     channel.write_ext(foo, start[0], length[0]);
01464 
01465                     len=length[0];
01466                     channel.setLocalWindowSize(channel.lwsize-len);
01467                     if(channel.lwsize<channel.lwsize_max/2){
01468                         packet.reset();
01469                         buf.putByte((byte)SSH_MSG_CHANNEL_WINDOW_ADJUST);
01470                         buf.putInt(channel.getRecipient());
01471                         buf.putInt(channel.lwsize_max-channel.lwsize);
01472                         write(packet);
01473                         channel.setLocalWindowSize(channel.lwsize_max);
01474                     }
01475                     break;
01476 
01477                 case SSH_MSG_CHANNEL_WINDOW_ADJUST:
01478                     buf.getInt(); 
01479                     buf.getShort(); 
01480                     i=buf.getInt(); 
01481                     channel=Channel.getChannel(i, this);
01482                     if(channel==null){
01483                         break;
01484                     }
01485                     int remoteSize = buf.getInt();
01486                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01487                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_DATA received, channel: "+i + ", bytes: " + remoteSize);
01488                     }
01489                     channel.addRemoteWindowSize(remoteSize); 
01490                     break;
01491 
01492                 case SSH_MSG_CHANNEL_EOF:
01493                     buf.getInt(); 
01494                     buf.getShort(); 
01495                     i=buf.getInt(); 
01496                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01497                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_EOF received, channel: "+i);
01498                     }
01499                     channel=Channel.getChannel(i, this);
01500                     if(channel!=null){
01501                         //channel.eof_remote=true;
01502                         //channel.eof();
01503                         channel.eof_remote();
01504                     }
01505                     /*
01506       packet.reset();
01507       buf.putByte((byte)SSH_MSG_CHANNEL_EOF);
01508       buf.putInt(channel.getRecipient());
01509       write(packet);
01510                      */
01511                     break;
01512                 case SSH_MSG_CHANNEL_CLOSE:
01513                     buf.getInt(); 
01514                     buf.getShort(); 
01515                     i=buf.getInt(); 
01516                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01517                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_CLOSE received, channel: "+i);
01518                     }
01519                     channel=Channel.getChannel(i, this);
01520                     if(channel!=null){
01521                         //        channel.close();
01522                         channel.disconnect();
01523                     }
01524                     /*
01525           if(Channel.pool.size()==0){
01526         thread=null;
01527       }
01528                      */
01529                     break;
01530                 case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
01531                     buf.getInt(); 
01532                     buf.getShort(); 
01533                     i=buf.getInt(); 
01534                     channel=Channel.getChannel(i, this);
01535                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01536                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_OPEN_CONFIRMATION received, channel: "+i);
01537                     }
01538                     if(channel==null){
01539                         //break;
01540                     }
01541                     int r=buf.getInt();
01542                     long rws=buf.getUInt();
01543                     int rps=buf.getInt();
01544 
01545                     channel.setRemoteWindowSize(rws);
01546                     channel.setRemotePacketSize(rps);
01547                     channel.open_confirmation=true;
01548                     channel.setRecipient(r);
01549                     break;
01550                 case SSH_MSG_CHANNEL_OPEN_FAILURE:
01551                     buf.getInt(); 
01552                     buf.getShort(); 
01553                     i=buf.getInt(); 
01554                     channel=Channel.getChannel(i, this);
01555                     if(channel==null){
01556                         //break;
01557                     }
01558                     int reason_code=buf.getInt(); 
01559                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01560                         // additional textual information
01561                         String descr =Util.byte2str(buf.getString());
01562                         //foo=buf.getString();  // language tag 
01563                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_OPEN_FAILURE received, reason: " + reason_code+", channel: "+i+", description: " + descr);
01564                     }
01565                     channel.setExitStatus(reason_code);
01566                     channel.close=true;
01567                     channel.eof_remote=true;
01568                     channel.setRecipient(0);
01569                     break;
01570                 case SSH_MSG_CHANNEL_REQUEST:
01571                     buf.getInt(); 
01572                     buf.getShort(); 
01573                     i=buf.getInt(); 
01574                     foo=buf.getString(); 
01575                     boolean reply=(buf.getByte()!=0);
01576                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01577                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_REQUEST received, channel: "+i +", type: " + foo + ", want reply: " + reply);
01578                     }
01579                     channel=Channel.getChannel(i, this);
01580                     if(channel!=null){
01581                         byte reply_type=(byte)SSH_MSG_CHANNEL_FAILURE;
01582                         if((Util.byte2str(foo)).equals("exit-status")){
01583                             i=buf.getInt();             // exit-status
01584                             channel.setExitStatus(i);
01585                             reply_type=(byte)SSH_MSG_CHANNEL_SUCCESS;
01586                         }
01587                         if(reply){
01588                             packet.reset();
01589                             buf.putByte(reply_type);
01590                             buf.putInt(channel.getRecipient());
01591                             write(packet);
01592                         }
01593                     }
01594                     else{
01595                     }
01596                     break;
01597                 case SSH_MSG_CHANNEL_OPEN:
01598                     buf.getInt(); 
01599                     buf.getShort(); 
01600                     foo=buf.getString();
01601                     String ctyp=Util.byte2str(foo);
01602                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01603                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_OPEN received, type: " + ctyp);
01604                     }
01605                     if(!"forwarded-tcpip".equals(ctyp) &&
01606                             !("x11".equals(ctyp) && x11_forwarding) &&
01607                             !("auth-agent@openssh.com".equals(ctyp) && agent_forwarding)){
01608                         //System.err.println("Session.run: CHANNEL OPEN "+ctyp); 
01609                         //throw new IOException("Session.run: CHANNEL OPEN "+ctyp);
01610                         packet.reset();
01611                         buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
01612                         buf.putInt(buf.getInt());
01613                         buf.putInt(Channel.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED);
01614                         buf.putString(Util.empty);
01615                         buf.putString(Util.empty);
01616                         write(packet);
01617                     }
01618                     else{
01619                         channel=Channel.getChannel(ctyp);
01620                         addChannel(channel);
01621                         channel.getData(buf);
01622                         channel.init();
01623 
01624                         Thread tmp=new Thread(channel);
01625                         tmp.setName("Channel "+ctyp+" "+host);
01626                         if(daemon_thread){
01627                             tmp.setDaemon(daemon_thread);
01628                         }
01629                         tmp.start();
01630                         break;
01631                     }
01632                 case SSH_MSG_CHANNEL_SUCCESS:
01633                     buf.getInt(); 
01634                     buf.getShort(); 
01635                     i=buf.getInt(); 
01636                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01637                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_SUCCESS received, channel: " + i);
01638                     }
01639                     channel=Channel.getChannel(i, this);
01640                     if(channel==null){
01641                         break;
01642                     }
01643                     channel.reply=1;
01644                     break;
01645                 case SSH_MSG_CHANNEL_FAILURE:
01646                     buf.getInt(); 
01647                     buf.getShort(); 
01648                     i=buf.getInt(); 
01649                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01650                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_CHANNEL_FAILURE received, channel: " + i);
01651                     }
01652                     channel=Channel.getChannel(i, this);
01653                     if(channel==null){
01654                         break;
01655                     }
01656                     channel.reply=0;
01657                     break;
01658                 case SSH_MSG_GLOBAL_REQUEST:
01659                     buf.getInt(); 
01660                     buf.getShort(); 
01661                     foo=buf.getString();       // request name
01662                     reply=(buf.getByte()!=0);
01663                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01664                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_GLOBAL_REQUEST received, request: " + Util.byte2str(foo) + ", want reply: " + reply);
01665                     }
01666                     if(reply){
01667                         // no global requests implemented
01668                         packet.reset();
01669                         buf.putByte((byte)SSH_MSG_REQUEST_FAILURE);
01670                         write(packet);
01671                     }
01672                     break;
01673                 case SSH_MSG_REQUEST_FAILURE:
01674                 case SSH_MSG_REQUEST_SUCCESS:
01675                     if(jsch.getLogger().isEnabled(Logger.INFO)) {
01676                         jsch.getLogger().log(Logger.INFO, "SSH_MSG_REQUEST_" +(msgType==SSH_MSG_REQUEST_SUCCESS ? "SUCCESS" : "FAILURE")+" received.");
01677                     }
01678                     Thread t=grr.getThread();
01679                     if(t!=null){
01680                         grr.setReply(msgType==SSH_MSG_REQUEST_SUCCESS? 1 : 0);
01681                         t.interrupt();
01682                     }
01683                     break;
01684                 default:
01685                     //System.err.println("Session.run: unsupported type "+msgType); 
01686                     throw new IOException("Unknown SSH message type "+msgType);
01687                 }
01688             }
01689         }
01690         catch(Exception e){
01691             in_kex=false;
01692             if(JSch.getLogger().isEnabled(Logger.INFO)){
01693                 JSch.getLogger().log(Logger.INFO,
01694                         "Caught an exception, leaving main loop due to " + e.getMessage());
01695             }
01696             //System.err.println("# Session.run");
01697             //e.printStackTrace();
01698         }
01699         try{
01700             disconnect();
01701         }
01702         catch(NullPointerException e){
01703             //System.err.println("@1");
01704             //e.printStackTrace();
01705         }
01706         catch(Exception e){
01707             //System.err.println("@2");
01708             //e.printStackTrace();
01709         }
01710         isConnected=false;
01711     }
01712 
01717     public void disconnect(){
01718         if(!isConnected) return;
01719         //System.err.println(this+": disconnect");
01720         //Thread.dumpStack();
01721         if(JSch.getLogger().isEnabled(Logger.INFO)){
01722             JSch.getLogger().log(Logger.INFO,
01723                     "Disconnecting from "+host+" port "+port);
01724         }
01725         /*
01726     for(int i=0; i<Channel.pool.size(); i++){
01727       try{
01728         Channel c=((Channel)(Channel.pool.elementAt(i)));
01729     if(c.session==this) c.eof();
01730       }
01731       catch(Exception e){
01732       }
01733     } 
01734          */
01735 
01736         Channel.disconnect(this);
01737 
01738         isConnected=false;
01739 
01740         PortWatcher.delPort(this);
01741         ChannelForwardedTCPIP.delPort(this);
01742         ChannelX11.removeFakedCookie(this);
01743 
01744         synchronized(lock){
01745             if(connectThread!=null){
01746                 Thread.yield();
01747                 connectThread.interrupt();
01748                 connectThread=null;
01749             }
01750         }
01751         thread=null;
01752         try{
01753             if(io!=null){
01754                 if(io.in!=null) io.in.close();
01755                 if(io.out!=null) io.out.close();
01756                 if(io.out_ext!=null) io.out_ext.close();
01757             }
01758             if(proxy==null){
01759                 if(socket!=null)
01760                     socket.close();
01761             }
01762             else{
01763                 synchronized(proxy){
01764                     proxy.close();    
01765                 }
01766                 proxy=null;
01767             }
01768         }
01769         catch(Exception e){
01770             //      e.printStackTrace();
01771         }
01772         io=null;
01773         socket=null;
01774         //    synchronized(jsch.pool){
01775         //      jsch.pool.removeElement(this);
01776         //    }
01777 
01778         jsch.removeSession(this);
01779 
01780         //System.gc();
01781     }
01782 
01788     public int setPortForwardingL(int lport, String host, int rport) throws JSchException{
01789         return setPortForwardingL("127.0.0.1", lport, host, rport);
01790     }
01801     public int setPortForwardingL(String boundaddress, int lport, String host, int rport) throws JSchException{
01802         return setPortForwardingL(boundaddress, lport, host, rport, null);
01803     }
01809     public int setPortForwardingL(String boundaddress, int lport, String host, int rport, ServerSocketFactory ssf) throws JSchException{
01810         PortWatcher pw=PortWatcher.addPort(this, boundaddress, lport, host, rport, ssf);
01811         Thread tmp=new Thread(pw);
01812         tmp.setName("PortWatcher Thread for "+host);
01813         if(daemon_thread){
01814             tmp.setDaemon(daemon_thread);
01815         }
01816         tmp.start();
01817         return pw.lport;
01818     }
01819 
01824     public void delPortForwardingL(int lport) throws JSchException{
01825         delPortForwardingL("127.0.0.1", lport);
01826     }
01832     public void delPortForwardingL(String boundaddress, int lport) throws JSchException{
01833         PortWatcher.delPort(this, boundaddress, lport);
01834     }
01835 
01845     public String[] getPortForwardingL() throws JSchException{
01846         return PortWatcher.getPortForwarding(this);
01847     }
01848 
01853     public void setPortForwardingR(int rport, String host, int lport) throws JSchException{
01854         setPortForwardingR(null, rport, host, lport, (SocketFactory)null);
01855     }
01860     public void setPortForwardingR(String bind_address, int rport, String host, int lport) throws JSchException{
01861         setPortForwardingR(bind_address, rport, host, lport, (SocketFactory)null);
01862     }
01867     public void setPortForwardingR(int rport, String host, int lport, SocketFactory sf) throws JSchException{
01868         setPortForwardingR(null, rport, host, lport, sf);
01869     }
01880     public void setPortForwardingR(String bind_address, int rport, String host, int lport, SocketFactory sf) throws JSchException{
01881         ChannelForwardedTCPIP.addPort(this, bind_address, rport, host, lport, sf);
01882         setPortForwarding(bind_address, rport);
01883     }
01884 
01891     public void setPortForwardingR(int rport, String daemon) throws JSchException{
01892         setPortForwardingR(null, rport, daemon, null);
01893     }
01899     public void setPortForwardingR(int rport, String daemon, Object[] arg) throws JSchException{
01900         setPortForwardingR(null, rport, daemon, arg);
01901     }
01902 
01922     public void setPortForwardingR(String bind_address, int rport, String daemon, Object[] arg) throws JSchException{
01923         ChannelForwardedTCPIP.addPort(this, bind_address, rport, daemon, arg);
01924         setPortForwarding(bind_address, rport);
01925     }
01926 
01927     private class GlobalRequestReply{
01928         private Thread thread=null;
01929         private int reply=-1;
01930         void setThread(Thread thread){
01931             this.thread=thread;
01932             this.reply=-1;
01933         }
01934         Thread getThread(){ return thread; }
01935         void setReply(int reply){ this.reply=reply; }
01936         int getReply(){ return this.reply; }
01937     }
01938     private GlobalRequestReply grr=new GlobalRequestReply();
01939     private void setPortForwarding(String bind_address, int rport) throws JSchException{
01940         synchronized(grr){
01941             Buffer buf=new Buffer(100); // ??
01942                     Packet packet=new Packet(buf);
01943 
01944                     String address_to_bind=ChannelForwardedTCPIP.normalize(bind_address);
01945 
01946                     grr.setThread(Thread.currentThread());
01947 
01948                     try{
01949                         // byte SSH_MSG_GLOBAL_REQUEST 80
01950                         // string "tcpip-forward"
01951                         // boolean want_reply
01952                         // string  address_to_bind
01953                         // uint32  port number to bind
01954                         packet.reset();
01955                         buf.putByte((byte) SSH_MSG_GLOBAL_REQUEST);
01956                         buf.putString(Util.str2byte("tcpip-forward"));
01957                         buf.putByte((byte)1);
01958                         buf.putString(Util.str2byte(address_to_bind));
01959                         buf.putInt(rport);
01960                         write(packet);
01961                     }
01962                     catch(Exception e){
01963                         grr.setThread(null);
01964                         if(e instanceof Throwable)
01965                             throw new JSchException(e.toString(), (Throwable)e);
01966                         throw new JSchException(e.toString());
01967                     }
01968 
01969                     int count = 0;
01970                     int reply = grr.getReply();
01971                     while(count < 10 && reply == -1){
01972                         try{ Thread.sleep(1000); }
01973                         catch(Exception e){
01974                         }
01975                         count++; 
01976                         reply = grr.getReply();
01977                     }
01978                     grr.setThread(null);
01979                     if(reply != 1){
01980                         throw new JSchException("remote port forwarding failed for listen port "+rport);
01981                     }
01982         }
01983     }
01984 
01989     public void delPortForwardingR(int rport) throws JSchException{
01990         ChannelForwardedTCPIP.delPort(this, rport);
01991     }
01992 
01993 
02005     private void initDeflater(String method) throws JSchException{
02006         if(method.equals("none")){
02007             deflater=null;
02008             return;
02009         }
02010         String foo=getConfig(method);
02011         if(foo!=null){
02012             if(method.equals("zlib") ||
02013                     (isAuthed && method.equals("zlib@openssh.com"))){
02014                 try{
02015                     Class c=Class.forName(foo);
02016                     deflater=(Compression)(c.newInstance());
02017                     int level=6;
02018                     try{ level=Integer.parseInt(getConfig("compression_level"));}
02019                     catch(Exception ee){ }
02020                     deflater.init(Compression.DEFLATER, level);
02021                 }
02022                 catch(Exception ee){
02023                     throw new JSchException(ee.toString(), ee);
02024                     //System.err.println(foo+" isn't accessible.");
02025                 }
02026             }
02027         }
02028     }
02029 
02041     private void initInflater(String method) throws JSchException{
02042         if(method.equals("none")){
02043             inflater=null;
02044             return;
02045         }
02046         String foo=getConfig(method);
02047         if(foo!=null){
02048             if(method.equals("zlib") ||
02049                     (isAuthed && method.equals("zlib@openssh.com"))){
02050                 try{
02051                     Class c=Class.forName(foo);
02052                     inflater=(Compression)(c.newInstance());
02053                     inflater.init(Compression.INFLATER, 0);
02054                 }
02055                 catch(Exception ee){
02056                     throw new JSchException(ee.toString(), ee);
02057                     //System.err.println(foo+" isn't accessible.");
02058                 }
02059             }
02060         }
02061     }
02062 
02063     void addChannel(Channel channel){
02064         channel.setSession(this);
02065     }
02066 
02076     public void setProxy(Proxy proxy){ this.proxy=proxy; }
02077 
02084     public void setHost(String host){ this.host=host; }
02085 
02092     public void setPort(int port){ this.port=port; }
02099     void setUserName(String username){ this.username=username; }
02100 
02107     public void setUserInfo(UserInfo userinfo){ this.userinfo=userinfo; }
02112     public UserInfo getUserInfo(){ return userinfo; }
02117     public void setInputStream(InputStream in){ this.in=in; }
02122     public void setOutputStream(OutputStream out){ this.out=out; }
02136     public void setX11Host(String host){ ChannelX11.setHost(host); }
02151     public void setX11Port(int port){ ChannelX11.setPort(port); }
02167     public void setX11Cookie(String cookie){ ChannelX11.setCookie(cookie); }
02168 
02175     public void setPassword(String password){
02176         if(password!=null)
02177             this.password=Util.str2byte(password);
02178     }
02191     public void setPassword(byte[] password){ 
02192         if(password!=null){
02193             this.password=new byte[password.length];
02194             System.arraycopy(password, 0, this.password, 0, password.length);
02195         }
02196     }
02197 
02205     public void setConfig(java.util.Properties newconf){
02206         setConfig((java.util.Hashtable)newconf);
02207     }
02208 
02216     public void setConfig(java.util.Hashtable newconf){
02217         synchronized(lock){
02218             if(config==null) 
02219                 config=new java.util.Hashtable();
02220             for(java.util.Enumeration e=newconf.keys() ; e.hasMoreElements() ;) {
02221                 String key=(String)(e.nextElement());
02222                 config.put(key, (String)(newconf.get(key)));
02223             }
02224         }
02225     }
02226 
02232     public void setConfig(String key, String value){
02233         synchronized(lock){ 
02234             if(config==null){
02235                 config=new java.util.Hashtable();
02236             }
02237             config.put(key, value);
02238         }
02239     }
02240 
02251     public String getConfig(String key){
02252         Object foo=null;
02253         if(config!=null){
02254             foo=config.get(key);
02255             if(foo instanceof String) return (String)foo;
02256         }
02257         foo=jsch.getConfig(key);
02258         if(foo instanceof String) return (String)foo;
02259         return null;
02260     }
02261 
02271     public void setSocketFactory(SocketFactory sfactory){ 
02272         socket_factory=sfactory;
02273     }
02280     public boolean isConnected(){ return isConnected; }
02285     public int getTimeout(){ return timeout; }
02295     public void setTimeout(int timeout) throws JSchException {
02296         if(socket==null){
02297             if(timeout<0){
02298                 throw new JSchException("invalid timeout value");
02299             }
02300             this.timeout=timeout;
02301             return;
02302         }
02303         try{
02304             socket.setSoTimeout(timeout);
02305             this.timeout=timeout;
02306         }
02307         catch(Exception e){
02308             if(e instanceof Throwable)
02309                 throw new JSchException(e.toString(), (Throwable)e);
02310             throw new JSchException(e.toString());
02311         }
02312     }
02313 
02319     public String getServerVersion(){
02320         return Util.byte2str(V_S);
02321     }
02322 
02328     public String getClientVersion(){
02329         return Util.byte2str(V_C);
02330     }
02341     public void setClientVersion(String cv){
02342         V_C=Util.str2byte(cv);
02343     }
02344 
02352     public void sendIgnore() throws Exception{
02353         Buffer buf=new Buffer();
02354         Packet packet=new Packet(buf);
02355         packet.reset();
02356         buf.putByte((byte)SSH_MSG_IGNORE);
02357         write(packet);
02358     }
02359 
02360     private static final byte[] keepalivemsg=Util.str2byte("keepalive@jcraft.com");
02361 
02366     public void sendKeepAliveMsg() throws Exception{
02367         Buffer buf=new Buffer();
02368         Packet packet=new Packet(buf);
02369         packet.reset();
02370         buf.putByte((byte)SSH_MSG_GLOBAL_REQUEST);
02371         buf.putString(keepalivemsg);
02372         buf.putByte((byte)1);
02373         write(packet);
02374     }
02375 
02376     private HostKey hostkey=null;
02377 
02384     public HostKey getHostKey(){ return hostkey; }
02385 
02389     public String getHost(){return host;}
02390 
02395     public String getUserName(){return username;}
02396 
02401     public int getPort(){return port;}
02409     public void setHostKeyAlias(String hostKeyAlias){
02410         this.hostKeyAlias=hostKeyAlias;
02411     }
02412 
02417     public String getHostKeyAlias(){
02418         return hostKeyAlias;
02419     }
02420 
02428     public void setServerAliveInterval(int interval) throws JSchException {
02429         setTimeout(interval);
02430         this.serverAliveInterval=interval;
02431     }
02432 
02440     public void setServerAliveCountMax(int count){
02441         this.serverAliveCountMax=count;
02442     }
02443 
02448     public int getServerAliveInterval(){
02449         return this.serverAliveInterval;
02450     }
02451 
02456     public int getServerAliveCountMax(){
02457         return this.serverAliveCountMax;
02458     }
02459 
02474     public void setDaemonThread(boolean enable){
02475         this.daemon_thread=enable;
02476     }
02477 
02478     private String[] checkCiphers(String ciphers){
02479         if(ciphers==null || ciphers.length()==0)
02480             return null;
02481 
02482         if(JSch.getLogger().isEnabled(Logger.INFO)){
02483             JSch.getLogger().log(Logger.INFO, 
02484                     "CheckCiphers: "+ciphers);
02485         }
02486 
02487         java.util.Vector result=new java.util.Vector();
02488         String[] _ciphers=Util.split(ciphers, ",");
02489         for(int i=0; i<_ciphers.length; i++){
02490             if(!checkCipher(getConfig(_ciphers[i]))){
02491                 result.addElement(_ciphers[i]);
02492             }
02493         }
02494         if(result.size()==0)
02495             return null;
02496         String[] foo=new String[result.size()];
02497         System.arraycopy(result.toArray(), 0, foo, 0, result.size());
02498 
02499         if(JSch.getLogger().isEnabled(Logger.INFO)){
02500             for(int i=0; i<foo.length; i++){
02501                 JSch.getLogger().log(Logger.INFO, 
02502                         foo[i]+" is not available.");
02503             }
02504         }
02505 
02506         return foo;
02507     }
02508 
02509     static boolean checkCipher(String cipher){
02510         try{
02511             Class c=Class.forName(cipher);
02512             Cipher _c=(Cipher)(c.newInstance());
02513             _c.init(Cipher.ENCRYPT_MODE,
02514                     new byte[_c.getBlockSize()],
02515                     new byte[_c.getIVSize()]);
02516             return true;
02517         }
02518         catch(Exception e){
02519             return false;
02520         }
02521     }
02522 
02523     private String[] checkKexes(String kexes){
02524         if(kexes==null || kexes.length()==0)
02525             return null;
02526 
02527         if(JSch.getLogger().isEnabled(Logger.INFO)){
02528             JSch.getLogger().log(Logger.INFO, 
02529                     "CheckKexes: "+kexes);
02530         }
02531 
02532         java.util.Vector result=new java.util.Vector();
02533         String[] _kexes=Util.split(kexes, ",");
02534         for(int i=0; i<_kexes.length; i++){
02535             if(!checkKex(this, getConfig(_kexes[i]))){
02536                 result.addElement(_kexes[i]);
02537             }
02538         }
02539         if(result.size()==0)
02540             return null;
02541         String[] foo=new String[result.size()];
02542         System.arraycopy(result.toArray(), 0, foo, 0, result.size());
02543 
02544         if(JSch.getLogger().isEnabled(Logger.INFO)){
02545             for(int i=0; i<foo.length; i++){
02546                 JSch.getLogger().log(Logger.INFO, 
02547                         foo[i]+" is not available.");
02548             }
02549         }
02550 
02551         return foo;
02552     }
02553 
02554     static boolean checkKex(Session s, String kex){
02555         try{
02556             Class c=Class.forName(kex);
02557             KeyExchange _c=(KeyExchange)(c.newInstance());
02558             _c.init(s ,null, null, null, null);
02559             return true;
02560         }
02561         catch(Exception e){ return false; }
02562     }
02563 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1