/** * Authenticate using some supported methods. If authentication fails, the method throws {@link * IOException}. * * @param c the connection to use for authentication * @throws IOException in case of IO error or authentication failure */ private void authenticate(final Connection c) throws IOException { for (String method : myHost.getPreferredMethods()) { if (c.isAuthenticationComplete()) { return; } if (PUBLIC_KEY_METHOD.equals(method)) { if (!myHost.supportsPubkeyAuthentication()) { continue; } if (!c.isAuthMethodAvailable(myHost.getUser(), PUBLIC_KEY_METHOD)) { continue; } File key = myHost.getIdentityFile(); if (key == null) { for (String a : myHost.getHostKeyAlgorithms()) { if (SSH_RSA_ALGORITHM.equals(a)) { if (tryPublicKey(c, idRSAPath)) { return; } } else if (SSH_DSS_ALGORITHM.equals(a)) { if (tryPublicKey(c, idDSAPath)) { return; } } } } else { if (tryPublicKey(c, key.getPath())) { return; } } } else if (KEYBOARD_INTERACTIVE_METHOD.equals(method)) { if (!c.isAuthMethodAvailable(myHost.getUser(), KEYBOARD_INTERACTIVE_METHOD)) { continue; } InteractiveSupport interactiveSupport = new InteractiveSupport(); for (int i = myHost.getNumberOfPasswordPrompts(); i > 0; i--) { if (c.isAuthenticationComplete()) { return; } if (c.authenticateWithKeyboardInteractive(myHost.getUser(), interactiveSupport)) { myLastError = ""; return; } else { myLastError = GitBundle.getString("sshmain.keyboard.interactive.failed"); } if (interactiveSupport.myPromptCount == 0 || interactiveSupport.myCancelled) { // the interactive callback has never been asked or it was cancelled, exit the loop myLastError = ""; break; } } } else if (PASSWORD_METHOD.equals(method)) { if (!myHost.supportsPasswordAuthentication()) { continue; } if (!c.isAuthMethodAvailable(myHost.getUser(), PASSWORD_METHOD)) { continue; } for (int i = myHost.getNumberOfPasswordPrompts(); i > 0; i--) { String password = myXmlRpcClient.askPassword(myHandlerNo, getUserHostString(), myLastError); if (password == null) { break; } else { if (c.authenticateWithPassword(myHost.getUser(), password)) { myLastError = ""; return; } else { myLastError = GitBundle.getString("sshmain.password.failed"); } } } } } throw new IOException("Authentication failed"); }
public boolean connect() { // try { // // connection.setCompression(true); // connection.setTCPNoDelay(true); // // } catch (IOException e) { // Log.e(TAG, "Could not enable compression!", e); // } // initialize the upstream proxy if (profile.isUpstreamProxy()) { try { if (profile.getUpstreamProxy() == null || profile.getUpstreamProxy().equals("")) throw new Exception(); String[] proxyInfo = profile.getUpstreamProxy().split("@"); if (proxyInfo.length == 1) { String[] hostInfo = proxyInfo[0].split(":"); if (hostInfo.length != 2) throw new Exception(); proxyData = new HTTPProxyData(hostInfo[0], Integer.valueOf(hostInfo[1])); } else if (proxyInfo.length == 2) { String[] userInfo = proxyInfo[0].split(":"); if (userInfo.length != 2) throw new Exception(); String[] hostInfo = proxyInfo[1].split(":"); if (hostInfo.length != 2) throw new Exception(); proxyData = new HTTPProxyData( hostInfo[0], Integer.valueOf(hostInfo[1]), userInfo[0], userInfo[1]); } else { throw new Exception(); } } catch (Exception e) { if (reason == null) reason = getString(R.string.upstream_format_error); return false; } } // get the host ip address if (proxyData != null) { try { hostAddress = InetAddress.getByName(proxyData.proxyHost).getHostAddress(); } catch (UnknownHostException e) { hostAddress = null; } } else { try { hostAddress = InetAddress.getByName(profile.getHost()).getHostAddress(); } catch (UnknownHostException e) { hostAddress = null; } } // fail to connect if the dns lookup failed if (hostAddress == null) { if (reason == null) reason = getString(R.string.fail_to_connect); return false; } // begin to connect try { connection = new Connection(profile.getHost(), profile.getPort()); if (proxyData != null) connection.setProxyData(proxyData); connection.addConnectionMonitor(this); /* * Uncomment when debugging SSH protocol: */ /* * DebugLogger logger = new DebugLogger() { * * public void log(int level, String className, String message) { * Log.d("SSH", message); } * * }; * * Logger.enabled = true; Logger.logger = logger; */ connection.connect(this, 10 * 1000, 20 * 1000); connected = true; } catch (Exception e) { Log.e(TAG, "Problem in SSH connection thread during connecting", e); // Display the reason in the text. if (reason == null) reason = getString(R.string.fail_to_connect); return false; } try { // enter a loop to keep trying until authentication int tries = 0; while (connected && !connection.isAuthenticationComplete() && tries++ < AUTH_TRIES) { authenticate(); // sleep to make sure we dont kill system Thread.sleep(1000); } } catch (Exception e) { Log.e(TAG, "Problem in SSH connection thread during authentication", e); if (reason == null) reason = getString(R.string.fail_to_authenticate); return false; } try { if (connection.isAuthenticationComplete()) { return enablePortForward(); } } catch (Exception e) { Log.e(TAG, "Problem in SSH connection thread during enabling port", e); if (reason == null) reason = getString(R.string.fail_to_connect); return false; } if (reason == null) reason = getString(R.string.fail_to_authenticate); Log.e(TAG, "Cannot authenticate"); return false; }