yiduwangkai / ganymed-ssh-2

Automatically exported from code.google.com/p/ganymed-ssh-2
Other
0 stars 0 forks source link

SSH fails when multiple connections are used concurently #33

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I have a problem when I try to use more than one connection. I have an object 
that creates multiple other objects, the second object has the code that uses 
the ganymed project. If I only use one of the second object it will connect 
prefectly with no issues. If I use more than one then the first one will 
connect and login, with no issues. When the second one starts to initialize it 
prints the error to the console, then instead of using its own connection it 
uses the first one, it will over-ride the connection of the first one and then 
login to the second device. This occurs with any number of connections and the 
last one is the only one that is actually connected.

What steps will reproduce the problem?
1. Using more than one connection will always reproduce the error.
2.
3.

What is the expected output? What do you see instead?
Since the connection is in an instance of an object each connection should be 
separate and independant.

What version of the product are you using? On what operating system?
I don't know how to check the version of the project that I have. I am using 
Windows XP.

Please provide any additional information below.

Exception in thread "Thread-2" java.lang.IllegalStateException: Connection is 
already authenticated!
        at ch.ethz.ssh2.Connection.authenticateWithPassword(Connection.java:326)
        at lister.SetupConnection(lister.java:208)
        at lister.run(lister.java:29)
        at java.lang.Thread.run(Unknown Source)

Original issue reported on code.google.com by michael....@gmail.com on 17 Jan 2014 at 6:14

GoogleCodeExporter commented 8 years ago
Oh, I forgot to mention. The second object uses a thread. It starts a thread to 
monitor the output of the ssh.

Original comment by michael....@gmail.com on 17 Jan 2014 at 7:25

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
The error message indicates that you called one of the authentication methods 
on a connection that is already authenticated. Please post some example code to 
demonstrate your threading problem.

Original comment by cleondris on 10 Feb 2014 at 11:24

GoogleCodeExporter commented 8 years ago
Greetings, I wasn't sure how much to remove from the source so I errored on the 
side of caution. I started from an example on this site as a starting point. 
The first file "lister.java" is called by "listerings.java" 

lister.java
// imports removed
public class lister extends JPanel implements Runnable {
    static String[][] LoginInfo = new String[10][4];
    static int count = 1;
    static Connection conn;
    static Session sess;
    static InputStream in;
    static OutputStream out;
    static FileWriter fw;
    static PrintWriter pw;
    static boolean writing = false;
    static int indexer = 0;
    Thread myThread;
    public static lister listing;
    boolean watching = false;
    static JButton button1;
    static JButton button2;

    public void run(  ) {
        SetupConnection();  //iniatize the connection to the ssh server
        try { Thread.sleep(1000); } catch ( InterruptedException ie ) {}
        SendCommands( 1 );  // send the listed commands to the ssh server
        try { Thread.sleep(500); } catch ( InterruptedException ie ) {}
        SetWriter(LoginInfo[indexer][3]);  // iniatialize the file to be writen
        MonitorOutput(); // watches for output from the ssh server, this is the reason why it needs to be in a thread
    }

    public lister ( ) {
        SetLoginInfo();
        setLayout(null);
        setVisible( true );
        setOpaque(true);
        setSize( 222, 32 );

        String [] items = { "SBC1", "SBC2", "SBC3", "SBC4", "SBC5", "SBC6", "SBC7", "SBC8", "SBC9", "SBC10", };
        final JComboBox comboBox = new JComboBox( items );
        comboBox.setEditable( false );
        comboBox.setLocation( 0, 4 );
        comboBox.setSize( 120, 25 );
        comboBox.setVisible( true );
        add( comboBox );
        comboBox.addActionListener( new ActionListener(  ) {
            public void actionPerformed(ActionEvent ae) {
                indexer = comboBox.getSelectedIndex();
        }});

        // JButton button1 = new JButton( "<html><font size=6 color=green>+</font></html>" );
        button1 = new JButton( "<html><font size=6 color=green>+</font></html>" );
        button1.setLocation( 127, 4 );
        button1.setSize( 45, 25 );
        button1.setVisible( true );
        button1.setEnabled( true );
        add( button1 );
        button1.addActionListener( new ActionListener(  ) {
            public void actionPerformed(ActionEvent ae) {
                // primaryEvent();
                JOptionPane.showMessageDialog(null, "This feature has been disabled. A trouble ticket has been submitted.");
            }
        });

        // JButton button2 = new JButton( "<html><font size=6 color=red>-</font></html>" );
        button2 = new JButton( "<html><font size=6 color=red>-</font></html>" );
        button2.setLocation( 175, 4 );
        button2.setSize( 45, 25 );
        button2.setVisible( true );
        button2.setEnabled( true );
        add( button2 );
        button2.addActionListener( new ActionListener(  ) {
            public void actionPerformed(ActionEvent ae) {
                // secondaryEvent();
                JOptionPane.showMessageDialog(null, "This feature has been disabled. A trouble ticket has been submitted.");
            }
        });

        repaint();
    }

    public void start() {
        button1.setEnabled( false );
        button2.setEnabled( false );
        myThread = new java.lang.Thread ( this );
        myThread.start(  );
    }

    public static void stop( String FileLoc ) {
        button1.setEnabled( true );
        button2.setEnabled( true );
        SendCommands( 2 );
        CloseWriter();
        if ( writing == false ) {
            File ren = new File ( LoginInfo[indexer][3] );
            String sip = "sipmsg.log";
            ren.renameTo( new File( sip ) );
            LogCorrector LC = new LogCorrector( sip );
            try { Process p = Runtime.getRuntime().exec( "log2cap" ); } catch ( IOException e ) {}
            try { Thread.sleep(500); } catch ( InterruptedException ie ) {}
            String output = LoginInfo[indexer][3].substring( 0, LoginInfo[indexer][3].length() - 4 ) + ".";
            output += FileLoc;
            ren = new File ( "sipmsg.log" );
            ren.renameTo( new File( output + ".log" ) );
            ren = new File ( "sipmsg.cap" );
            ren.renameTo( new File( output + ".cap" ) );
        }
        CloseConnection();
    }

    public void setWatching( boolean watch ) {
        watching = watch;
        // System.out.println( watching );
    }

    public static void CloseConnection() {
        // Close this session and the connection
        sess.close();
        conn.close();
    }

    public void addgenericlistener(genericlistener listener) {
        listenerList.add( genericlistener.class, listener );
    }
    public void removegenericlistener(genericlistener listener) {
        listenerList.remove( genericlistener.class, listener );
    }
    public void primaryEvent(  ) {   // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).primary( new genericevent( this ) );
    }
    public void secondaryEvent(  ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).secondary( new genericevent( this ) );
    }
    public void prtyEvent( int a, int b ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).prtycng( new genericevent( this ), a, b );
    }
    public void relayEvent( String a ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).relay( new genericevent( this ), a );
    }

    public static void SetLoginInfo() {
        // removed
    }

    public static void SetupConnection() {
        try {
            // Create a connection instance
            conn = new Connection( LoginInfo[indexer][0] );

            // Now connect
            conn.connect();

            // Authenticate
            boolean isAuthenticated = conn.authenticateWithPassword(LoginInfo[indexer][1], LoginInfo[indexer][2]);

            if (isAuthenticated == false)
                throw new IOException("Authentication failed.");

            // Create a session
            sess = conn.openSession();

            in = sess.getStdout();
            out = sess.getStdin();

            int x_width = 90;
            int y_width = 30;

            sess.requestPTY("dumb", x_width, y_width, 0, 0, null);
            sess.startShell();

        } catch (IOException e) {
            e.printStackTrace(System.err);
            System.out.print( "error in connect" );
            System.exit(2);
        }

    }

    public static void SendCommands( int mode ) {
        try{
            String[] commands = new String[3];
            if ( mode == 1 ) {
                commands[0] = "y\n";
                commands[1] = "not sipd siplog\n";
                commands[2] = "tail-logfile-open sipd sipmsg.log\n";
            } else if ( mode == 2 ) {
                commands[0] = "not sipd nosiplog\n";
                commands[1] = "exit\n";
                commands[2] = "\n";
            }

            for ( int i = 0; i < commands.length; i++) {
                byte[] byteArray = commands[i].getBytes();
                out.write(byteArray);
                out.flush();
            }

        } catch (IOException e) {
            e.printStackTrace(System.err);
            System.exit(2);
        }
    }

    public static void SetWriter( String file ) {
        try {
            File out = new File( file );
            fw = new FileWriter ( out );
            pw = new PrintWriter( fw );
        } catch ( IOException e ) {}
    }

    public void MonitorOutput() {
        try {
            // Advanced:
            // The following is a demo on how one can read from stdout and
            // stderr without having to use two parallel worker threads (i.e.,
            // we don't use the Streamgobblers here) and at the same time not
            // risking a deadlock (due to a filled SSH2 channel window, caused
            // by the stream which you are currently NOT reading from =).

            // Don't wrap these streams and don't let other threads work on
            // these streams while you work with Session.waitForCondition()!!!

            InputStream stdout = sess.getStdout();
            InputStream stderr = sess.getStderr();

            byte[] buffer = new byte[8192];

            while (true) {
                if ((stdout.available() == 0) && (stderr.available() == 0)) {
                    // Even though currently there is no data available, it may be that new data arrives
                    // and the session's underlying channel is closed before we call waitForCondition().
                    // This means that EOF and STDOUT_DATA (or STDERR_DATA, or both) may
                    // be set together.

                    int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 2000);

                    // Wait no longer than 2 seconds (= 2000 milliseconds)
                    if ((conditions & ChannelCondition.TIMEOUT) != 0) {
                        // A timeout occured.
                        //throw new IOException("Timeout while waiting for data from peer.");
                    }

                    // Here we do not need to check separately for CLOSED, since CLOSED implies EOF
                    if ((conditions & ChannelCondition.EOF) != 0) {
                        // The remote side won't send us further data...
                        if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0) {
                            // ... and we have consumed all data in the local arrival window.
                            break;
                        }
                    }

                    // OK, either STDOUT_DATA or STDERR_DATA (or both) is set.

                    // You can be paranoid and check that the library is not going nuts:
                    // if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
                    // throw new IllegalStateException("Unexpected condition result (" + conditions + ")");
                }

                // If you below replace "while" with "if", then the way the output appears on the local
                // stdout and stder streams is more "balanced". Addtionally reducing the buffer size
                // will also improve the interleaving, but performance will slightly suffer.
                // OKOK, that all matters only if you get HUGE amounts of stdout and stderr data =)

                while (stdout.available() > 0) {
                    int len = stdout.read(buffer);
                    //if (len > 0) // this check is somewhat paranoid
                    //  System.out.write(buffer, 0, len);
                    SaveOutput( len, buffer );
                    buffer = new byte[8192];
                }

                while (stderr.available() > 0) {
                    int len = stderr.read(buffer);
                    //if (len > 0) // this check is somewhat paranoid
                    //  System.err.write(buffer, 0, len);
                    SaveOutput( len, buffer );
                    buffer = new byte[8192];
                }
            }

        } catch (IOException e) {
            e.printStackTrace(System.err);
            System.exit(2);
        }
    }

    public void SaveOutput( int len, byte[] buffer ) {
        boolean[] output = new boolean [4];
        output[0] = false; // write to console
        output[1] = true; // write to file
        output[2] = true; // write to window

        writing = ( count == 7 ? true : false );

        String stdout = new String();
        stdout = new String(buffer);
        stdout = stdout.trim();

        if ( output[0] ) System.out.println( stdout );
        if ( output[1] && writing ) {
            stdout = stdout.replaceAll("\r\r","\r");
            stdout = stdout.replaceAll("----------------------------------------","----------------------------------------\r\n");
            while ( stdout.contains( "----------------------------------------\r\n\r\n" ) )
                stdout = stdout.replaceAll("----------------------------------------\r\n\r\n","----------------------------------------\r\n");
            pw.print( stdout );
        }
        if ( output[2] && watching ) relayEvent( stdout );
        if ( count < 7 ) count++;
    }

    public static void CloseWriter() {
        try { fw.close(  ); }
        catch ( IOException e ) {}
        writing = false;
    }
}

listerings.java
//imports removed

public class listerings extends JPanel {

    static lister listing[] = new lister[12];
    static JFrame frame;
    private static int indexer = 0;
    static listerings listering;

    public listerings ( ) {

        setLayout(null);
        setVisible( true );
        setOpaque(true);
        setSize( 222, 300 );  // change size

        repaint();
    }

    public void addListing( int index ) {
        if ( index < 10 ) {
            listing[index] = new lister();
            listing[index].setLocation( 0, ( 32  * ( index ) ));
            // listering.add( listing[index] );
            add( listing[index] );
            listing[index].addgenericlistener( new genericlistener() {
                public void primary(genericevent e) {
                    addListing( indexer );
                }
                public void secondary(genericevent e) {
                    if ( indexer > 1 ) {
                        removeListing();
                    }
                }
                public void prtycng(genericevent e, int a, int b ) {}
                public void relay(genericevent e, String a ) {
                    // System.out.println( a );
                    // System.out.println( indexer );
                    if ( indexer == 1 ) relayEvent( a );
                }
            });
            indexer++;
        }
        setSize( 222, ( 32  * ( indexer ) ) );
        prtyEvent( getSize().width, getSize().height );
        if ( indexer == 1 ) primaryEvent();
        else secondaryEvent();

        repaint();
    }

    private void removeListing() {
        // listering.remove( listing[ indexer - 1 ] );
        remove( listing[ indexer - 1 ] );
        listing[indexer] = null;
        indexer--;
        setSize( 222, ( 32  * ( indexer ) ) );
        prtyEvent( getSize().width, getSize().height );
        if ( indexer == 1 ) primaryEvent();
        else secondaryEvent();

        repaint();
    }

    public void start() {

        for ( int i = 0; i < indexer; i++ ) {

            listing[i].start();

        }

    }

    public void stop( String arg1 ) {

        for ( int i = 0; i < indexer; i++ ) {

            listing[i].stop( arg1 );

        }

    }

    public void setWatching( boolean watch ) {

        if ( indexer == 1 ) {

            // System.out.println( watch );
            listing[0].setWatching( watch );

        }

    }

    public void addgenericlistener(genericlistener listener) {
        listenerList.add( genericlistener.class, listener );
    }
    public void removegenericlistener(genericlistener listener) {
        listenerList.remove( genericlistener.class, listener );
    }
    public void primaryEvent(  ) {   // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).primary( new genericevent( this ) );
    }
    public void secondaryEvent(  ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).secondary( new genericevent( this ) );
    }
    public void prtyEvent( int a, int b ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).prtycng( new genericevent( this ), a, b );
    }
    public void relayEvent( String a ) {  // possibly make private
        Object[] listeners = listenerList.getListenerList(  );
        for ( int i = 0; i < listeners.length; i += 2 )
            if ( listeners[i] == genericlistener.class )
                ((genericlistener)listeners[i + 1]).relay( new genericevent( this ), a );
    }

    public static void main( String[] args ) {

        // JFrame frame = new JFrame( "listerings" );
        frame = new JFrame( "listerings" );
        frame.setLayout(null);
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setVisible( true );
        frame.getContentPane().setBackground( Color.red );

        // listerings listering = new listerings();
        listering = new listerings();
        listering.setLocation( 10, 45 );
        frame.add( listering );
        listering.addListing(0);
        listering.addgenericlistener( new genericlistener() {
            public void primary(genericevent e) {}
            public void secondary(genericevent e) {}
            public void prtycng(genericevent e, int a, int b ) {}
            public void relay(genericevent e, String a ) {}
        });

        frame.repaint();
    }
}

Original comment by michael....@gmail.com on 11 Feb 2014 at 3:29