public void run() { try { state.setValue(TransportProtocolState.NEGOTIATING_PROTOCOL); log.info("Registering transport protocol messages with inputstream"); algorithmsOut = new TransportProtocolAlgorithmSync(); algorithmsIn = new TransportProtocolAlgorithmSync(); // Create the input/output streams sshIn = new TransportProtocolInputStream(this, provider.getInputStream(), algorithmsIn); sshOut = new TransportProtocolOutputStream(provider.getOutputStream(), this, algorithmsOut); // Register the transport layer messages that this class will handle messageStore.registerMessage(SshMsgDisconnect.SSH_MSG_DISCONNECT, SshMsgDisconnect.class); messageStore.registerMessage(SshMsgIgnore.SSH_MSG_IGNORE, SshMsgIgnore.class); messageStore.registerMessage( SshMsgUnimplemented.SSH_MSG_UNIMPLEMENTED, SshMsgUnimplemented.class); messageStore.registerMessage(SshMsgDebug.SSH_MSG_DEBUG, SshMsgDebug.class); messageStore.registerMessage(SshMsgKexInit.SSH_MSG_KEX_INIT, SshMsgKexInit.class); messageStore.registerMessage(SshMsgNewKeys.SSH_MSG_NEWKEYS, SshMsgNewKeys.class); registerTransportMessages(); List list = SshKeyExchangeFactory.getSupportedKeyExchanges(); Iterator it = list.iterator(); while (it.hasNext()) { String keyExchange = (String) it.next(); SshKeyExchange kex = SshKeyExchangeFactory.newInstance(keyExchange); kex.init(this); kexs.put(keyExchange, kex); } // call abstract to initialise the local ident string setLocalIdent(); // negotiate the protocol version negotiateVersion(); startBinaryPacketProtocol(); } catch (Throwable e) { if (e instanceof IOException) { state.setLastError((IOException) e); } if (state.getValue() != TransportProtocolState.DISCONNECTED) { log.error("The Transport Protocol thread failed", e); // log.info(e.getMessage()); stop(); } } finally { thread = null; } log.debug("The Transport Protocol has been stopped"); }
/** * @throws IOException * @throws KeyExchangeException */ protected void beginKeyExchange() throws IOException, KeyExchangeException { log.info("Starting key exchange"); // state.setValue(TransportProtocolState.PERFORMING_KEYEXCHANGE); String kexAlgorithm = ""; // We now have both kex inits, this is where client/server // implemtations take over so call abstract methods try { // Determine the key exchange algorithm kexAlgorithm = getKexAlgorithm(); if (log.isDebugEnabled()) { log.debug("Key exchange algorithm: " + kexAlgorithm); } // Get an instance of the key exchange algortihm SshKeyExchange kex = (SshKeyExchange) kexs.get(kexAlgorithm); // Do the key exchange performKeyExchange(kex); // Record the output exchangeHash = kex.getExchangeHash(); if (sessionIdentifier == null) { sessionIdentifier = new byte[exchangeHash.length]; System.arraycopy(exchangeHash, 0, sessionIdentifier, 0, sessionIdentifier.length); thread.setSessionId(sessionIdentifier); } hostKey = kex.getHostKey(); signature = kex.getSignature(); k = kex.getSecret(); // Send new keys sendNewKeys(); kex.reset(); } catch (AlgorithmNotAgreedException e) { sendDisconnect( SshMsgDisconnect.KEY_EXCHANGE_FAILED, "No suitable key exchange algorithm was agreed"); throw new KeyExchangeException("No suitable key exchange algorithm could be agreed."); } }