public void connect(int connectTimeout) 
		{
			if(_isConnected)
			{
				throw new JSchException("session is already connected");
			}
			io=new IO();
			if(random==null)
			{
				try
				{
					Class c=Class.forName(getConfig("random"));
					random=(Random)(c.newInstance());
				}
				catch(Exception e)
				{
					System.Console.Error.WriteLine("connect: random "+e);
				}
			}
			Packet.setRandom(random);

			try	
			{
				int i, j;
				int pad=0;

				if(proxy==null)
				{
					proxy=jsch.getProxy(host);
					if(proxy!=null)
					{
						lock(proxy)
						{
							proxy.close();
						}
					}
				}

				if(proxy==null)
				{
					Stream In;
					Stream Out;
					if(socket_factory==null)
					{
						socket=Util.createSocket(host, port, connectTimeout);
						In=socket.getInputStream();
						Out=socket.getOutputStream();
					}
					else
					{
						socket=socket_factory.createSocket(host, port);
						In=socket_factory.getInputStream(socket);
						Out=socket_factory.getOutputStream(socket);
					}
					//if(timeout>0){ socket.setSoTimeout(timeout); }
					socket.setTcpNoDelay(true);
					io.setInputStream(In);
					io.setOutputStream(Out);
				}
				else
				{
					lock(proxy)
					{
						proxy.connect(socket_factory, host, port, connectTimeout);
						io.setInputStream(proxy.getInputStream());
						io.setOutputStream(proxy.getOutputStream());
						socket=proxy.getSocket();
					}
				}

				if(connectTimeout>0 && socket!=null)
				{
					socket.setSoTimeout(connectTimeout);
				}

				_isConnected=true;

				while(true)
				{

					i=0;
					j=0;
					while(i<buf.buffer.Length)
					{
						j=io.getByte();
						if(j<0)break;
						buf.buffer[i]=(byte)j; i++;
						if(j==10)break;
					}
					if(j<0)
					{
						throw new JSchException("connection is closed by foreign host");
					}

					if(buf.buffer[i-1]==10)
					{    // 0x0a
						i--;
						if(buf.buffer[i-1]==13)
						{  // 0x0d
							i--;
						}
					}

					if(i>4 && (i!=buf.buffer.Length) &&
						(buf.buffer[0]!='S'||buf.buffer[1]!='S'||
						buf.buffer[2]!='H'||buf.buffer[3]!='-'))
					{
						//System.err.println(new String(buf.buffer, 0, i);
						continue;
					}

					if(i==buf.buffer.Length ||
						i<7 ||                                      // SSH-1.99 or SSH-2.0
						(buf.buffer[4]=='1' && buf.buffer[6]!='9')  // SSH-1.5
						)
					{
						throw new JSchException("invalid server's version String");
					}
					break;
				}				

				V_S=new byte[i]; Tamir.SharpSsh.java.System.arraycopy(buf.buffer, 0, V_S, 0, i);
				//System.Console.WriteLine("V_S: ("+i+") ["+new String(V_S)+"]");

				//io.put(V_C, 0, V_C.Length); io.put("\n".getBytes(), 0, 1);
			{
				// Some Cisco devices will miss to read '\n' if it is sent separately.
				byte[] foo=new byte[V_C.Length+1];
				Tamir.SharpSsh.java.System.arraycopy(V_C, 0, foo, 0, V_C.Length);
				foo[foo.Length-1]=(byte)'\n';
				io.put(foo, 0, foo.Length);
			}

				buf=read(buf);
				//System.Console.WriteLine("read: 20 ? "+buf.buffer[5]);
				if(buf.buffer[5]!=SSH_MSG_KEXINIT)
				{
					throw new JSchException("invalid protocol: "+buf.buffer[5]);
				}
				KeyExchange kex=receive_kexinit(buf);

				while(true)
				{
					buf=read(buf);
					if(kex.getState()==buf.buffer[5])
					{
						bool result=kex.next(buf);
						if(!result)
						{
							//System.Console.WriteLine("verify: "+result);
							in_kex=false;
							throw new JSchException("verify: "+result);
						}
					}
					else
					{
						in_kex=false;
						throw new JSchException("invalid protocol(kex): "+buf.buffer[5]);
					}
					if(kex.getState()==KeyExchange.STATE_END)
					{
						break;
					}
				}

				try{ checkHost(host, kex); }
				catch(JSchException ee)
				{
					in_kex=false;
					throw ee;
				}

				send_newkeys();

				// receive SSH_MSG_NEWKEYS(21)
				buf=read(buf);
				//System.Console.WriteLine("read: 21 ? "+buf.buffer[5]);
				if(buf.buffer[5]==SSH_MSG_NEWKEYS)
				{
					receive_newkeys(buf, kex);
				}
				else
				{
					in_kex=false;
					throw new JSchException("invalid protocol(newkyes): "+buf.buffer[5]);
				}

				bool auth=false;
				bool auth_cancel=false;

				UserAuthNone usn=new UserAuthNone(userinfo);
				auth=usn.start(this);

				String methods=null;
				if(!auth)
				{
					methods=usn.getMethods();
					if(methods!=null)
					{
						methods=methods.toLowerCase();
					}
					else
					{
						// methods: publickey,password,keyboard-interactive
						methods="publickey,password,keyboard-interactive";
					}
				}

			loop:
				while(true)
				{

					//System.Console.WriteLine("methods: "+methods);

					while(!auth &&
						methods!=null && methods.Length()>0)
					{

						//System.Console.WriteLine("  methods: "+methods);

						UserAuth us=null;
						if(methods.startsWith("publickey"))
						{
							//System.Console.WriteLine("   jsch.identities.size()="+jsch.identities.size());
							lock(jsch.identities)
							{
								if(jsch.identities.size()>0)
								{
									us=new UserAuthPublicKey(userinfo);
								}
							}
						}
						else if(methods.startsWith("keyboard-interactive"))
						{
							if(userinfo is UIKeyboardInteractive)
							{
								us=new UserAuthKeyboardInteractive(userinfo);
							}
						}
						else if(methods.startsWith("password"))
						{
							us=new UserAuthPassword(userinfo);
						}
						if(us!=null)
						{
							try
							{
								auth=us.start(this);
								auth_cancel=false;
							}
							catch(JSchAuthCancelException ee)
							{
								//System.Console.WriteLine(ee);
								auth_cancel=true;
							}
							catch(JSchPartialAuthException ee)
							{
								methods=ee.getMethods();
								//System.Console.WriteLine("PartialAuth: "+methods);
								auth_cancel=false;
								continue;//loop;
							}
							catch(RuntimeException ee)
							{
								throw ee;
							}
							catch(Exception ee)
							{
								System.Console.WriteLine("ee: "+ee); // SSH_MSG_DISCONNECT: 2 Too many authentication failures
							}
						}
						if(!auth)
						{
							int comma=methods.indexOf(",");
							if(comma==-1) break;
							methods=methods.subString(comma+1);
						}
					}
					break;
				}

				if(connectTimeout>0 || timeout>0)
				{
					socket.setSoTimeout(timeout);
				}

				if(auth)
				{
					isAuthed=true;
					connectThread=new Thread(this);
					connectThread.setName("Connect thread "+host+" session");
					connectThread.start();
					return;
				}
				if(auth_cancel)
					throw new JSchException("Auth cancel");
				throw new JSchException("Auth fail");
			}
			catch(Exception e) 
			{
				in_kex=false;
				if(_isConnected)
				{
					try
					{
						packet.reset();
						buf.putByte((byte)SSH_MSG_DISCONNECT);
						buf.putInt(3);
						buf.putString(new String(e.ToString()).getBytes());
						buf.putString(new String("en").getBytes());
						write(packet);
						disconnect();
					}
					catch(Exception ee)
					{
					}
				}
				_isConnected=false;
				//e.printStackTrace();
				if(e is RuntimeException) throw (RuntimeException)e;
				if(e is JSchException) throw (JSchException)e;
				throw new JSchException("Session.connect: "+e);
			}
		}
Example #2
0
        public void connect(int connectTimeout)
        {
            if(random==null)
            {
                try
                {
                    Type t=Type.GetType(getConfig("random"));
                    random=(Random)(Activator.CreateInstance(t));
                }
                catch(Exception e){ Console.Error.WriteLine("connect: random "+e); }
            }
            Packet.setRandom(random);

            try
            {
                int i, j;
                //int pad=0;

                if(proxy==null)
                {
                    proxy=jsch.getProxy(host);
                    if(proxy!=null)
                    {
                        lock(proxy)
                        {
                            proxy.close();
                        }
                    }
                }
                IPEndPoint ipe=null;
                if(proxy==null)
                {
                    Stream ins;
                    Stream outs;
                    if(socket_factory==null)
                    {
                        if(connectTimeout==0)
                        {
                            ipe = new IPEndPoint(Dns.GetHostByName(host).AddressList[0], port);
                            socket=new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                        }
                        //			String message="";
                        //			Thread tmp=new Thread(new Runnable(){
                        //			public void run(){
                        //			try{
                        //				sockp[0]=new Socket(host, port);
                        //				if(done[0]){
                        //				if(sockp[0]!=null){
                        //				sockp[0].close();
                        //				sockp[0]=null;
                        //				}
                        //				}
                        //				else thread.interrupt();
                        //			}
                        //			catch(Exception e){
                        //				ee[0]=e;
                        //				thread.interrupt();
                        //				if(sockp[0]!=null){
                        //				try{
                        //				sockp[0].close();
                        //				sockp[0]=null;
                        //				}catch(Exception eee){}
                        //				}
                        //			}
                        //			}
                        //			});
                        //			tmp.start();
                        //			try{
                        //			Thread.sleep(connectTimeout);
                        //			message="timeout: ";
                        //			}
                        //			catch(java.lang.InterruptedException eee){
                        //			tmp.interrupt();
                        //			tmp=null;
                        //			System.gc();
                        //			}
                        //			done[0]=true;
                        //			if(sockp[0]!=null){
                        //			socket=sockp[0];
                        //			}
                        //			else{
                        //			message+="socket is not established";
                        //			if(ee[0]!=null){
                        //			message=ee[0].toString();
                        //			}
                        //			throw new JSchException(message);
                        //			}
                        //		}
                        socket.Connect(ipe);
                        NetworkStream ns = new NetworkStream( socket );
                        ins=ns;
                        outs=ns;
                    }
                    else
                    {
                        socket=socket_factory.createSocket(host, port);
                        ins=socket_factory.getInputStream(socket);
                        outs=socket_factory.getOutputStream(socket);
                    }
                    if(timeout>0)
                    {
                        socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, timeout);
                    }
                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
                    io.setInputStream(ins);
                    io.setOutputStream(outs);
                }
                else
                {
                    lock(proxy)
                    {
                        proxy.connect(this, host, port);
                        io.setInputStream(proxy.getInputStream());
                        io.setOutputStream(proxy.getOutputStream());
                    }
                }

                isConnected=true;

                i=0;
                while(i<buf.buffer.Length)
                {
                    j=io.getByte();
                    buf.buffer[i]=(byte)j; i++;
                    if(j==10)break;
                }

                if(buf.buffer[i-1]==10)
                {    // 0x0a
                    i--;
                    if(buf.buffer[i-1]==13)
                    {  // 0x0d
                        i--;
                    }
                }

                if(i==buf.buffer.Length ||
                    i<7 ||                                      // SSH-1.99 or SSH-2.0
                    (buf.buffer[4]=='1' && buf.buffer[6]!='9')  // SSH-1.5
                    )
                {
                    throw new JSchException("invalid server's version string");
                }

                V_S=new byte[i]; Array.Copy(buf.buffer, 0, V_S, 0, i);
                //Console.WritLine("V_S: ("+i+") ["+new String(V_S)+"]");

                //io.put(V_C, 0, V_C.length); io.put("\n".getBytes(), 0, 1);
            {
                // Some Cisco devices will miss to read '\n' if it is sent separately.
                byte[] foo=new byte[V_C.Length+1];
                Array.Copy(V_C, 0, foo, 0, V_C.Length);
                foo[foo.Length-1]=(byte)'\n';
                io.put(foo, 0, foo.Length);
            }

                buf=read(buf);
                //Console.WritLine("read: 20 ? "+buf.buffer[5]);
                if(buf.buffer[5]!=SSH_MSG_KEXINIT)
                {
                    throw new JSchException("invalid protocol: "+buf.buffer[5]);
                }
                KeyExchange kex=receive_kexinit(buf);

                bool result;
                while(true)
                {
                    buf=read(buf);
                    if(kex.getState()==buf.buffer[5])
                    {
                        result=kex.next(buf);
                        if(!result)
                        {
                            //Console.WritLine("verify: "+result);
                            throw new JSchException("verify: "+result);
                        }
                    }
                    else
                    {
                        throw new JSchException("invalid protocol(kex): "+buf.buffer[5]);
                    }
                    if(kex.getState()==KeyExchange.STATE_END)
                    {
                        break;
                    }
                }

                checkHost(host, kex);

                send_newkeys();

                // receive SSH_MSG_NEWKEYS(21)
                buf=read(buf);
                //Console.WritLine("read: 21 ? "+buf.buffer[5]);
                if(buf.buffer[5]==SSH_MSG_NEWKEYS)
                {
                    receive_newkeys(buf, kex);
                }
                else
                {
                    throw new JSchException("invalid protocol(newkyes): "+buf.buffer[5]);
                }

                bool auth=false;
                bool auth_cancel=false;

                UserAuthNone usn=new UserAuthNone(userinfo);
                auth=usn.start(this);

                String methods=usn.getMethods();
                // methods: publickey,password,keyboard-interactive
                if(methods==null)
                {
                    methods="publickey,password,keyboard-interactive";
                }

                //loop:
                while(true)
                {

                    //Console.WritLine("methods: "+methods);

                    while(!auth &&
                        methods!=null && methods.Length>0)
                    {

                        //Console.WritLine("  methods: "+methods);

                        UserAuth us=null;
                        if(methods.StartsWith("publickey"))
                        {
                            //Console.WritLine("   jsch.identities.size()="+jsch.identities.size());
                            lock(jsch.identities)
                            {
                                if(jsch.identities.Count>0)
                                {
                                    us=new UserAuthPublicKey(userinfo);
                                }
                            }
                        }
                        else if(methods.StartsWith("keyboard-interactive"))
                        {
                            if(userinfo is UIKeyboardInteractive)
                            {
                                us=new UserAuthKeyboardInteractive(userinfo);
                            }
                        }
                        else if(methods.StartsWith("password"))
                        {
                            us=new UserAuthPassword(userinfo);
                        }
                        if(us!=null)
                        {
                            try
                            {
                                auth=us.start(this);
                                auth_cancel=false;
                            }
                            catch(JSchAuthCancelException ee)
                            {
                                Console.WriteLine(ee);
                                auth_cancel=true;
                            }
                            catch(JSchPartialAuthException ee)
                            {
                                methods=ee.getMethods();
                                //Console.WritLine("PartialAuth: "+methods);
                                auth_cancel=false;
                                continue /*loop*/;
                            }
                            catch(Exception ee)
                            {
                                throw ee;
                            }
                        }
                        if(!auth)
                        {
                            int comma=methods.IndexOf(",");
                            if(comma==-1) break;
                            methods=methods.Substring(comma+1);
                        }
                    }
                    break;
                }

                if(auth)
                {
                    connectThread=new System.Threading.Thread(new System.Threading.ThreadStart(run));
                    connectThread.Start();
                    return;
                }
                if(auth_cancel)
                    throw new JSchException("Auth cancel");
                throw new JSchException("Auth fail");
            }
            catch(Exception e)
            {
                if(isConnected)
                {
                    try
                    {
                        packet.reset();
                        buf.putByte((byte)SSH_MSG_DISCONNECT);
                        buf.putInt(3);
                        buf.putString(Util.getBytes(e.ToString()));
                        buf.putString(Util.getBytes( "en" ));
                        write(packet);
                        disconnect();
                    }
                    catch
                    {
                    }
                }
                isConnected=false;
                //e.printStackTrace();
                //if(e is JSchException) throw (JSchException)e;
                //throw new JSchException("Session.connect: "+e);
                throw e;
            }
        }