package org.tmatesoft.svn.core.javahl17; import java.io.File; import java.security.cert.X509Certificate; import java.text.MessageFormat; import org.apache.subversion.javahl.callback.UserPasswordCallback; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider; import org.tmatesoft.svn.core.auth.SVNAuthentication; import org.tmatesoft.svn.core.auth.SVNPasswordAuthentication; import org.tmatesoft.svn.core.auth.SVNSSHAuthentication; import org.tmatesoft.svn.core.auth.SVNSSLAuthentication; import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication; import org.tmatesoft.svn.core.internal.util.SVNSSLUtil; import org.tmatesoft.svn.core.internal.wc.ISVNSSLPasspharsePromptSupport; class JavaHLAuthenticationProvider implements ISVNAuthenticationProvider, ISVNSSLPasspharsePromptSupport { //TODO: what is the constant about? private static final String ADAPTER_DEFAULT_PROMPT_CLASS = "org.tigris.subversion.svnclientadapter.javahl.AbstractJhlClientAdapter$DefaultPromptUserPassword"; private UserPasswordCallback prompt; public JavaHLAuthenticationProvider(UserPasswordCallback prompt){ this.prompt = prompt; } public SVNAuthentication requestClientAuthentication(String kind, SVNURL url, String realm, SVNErrorMessage errorMessage, SVNAuthentication previousAuth, boolean authMayBeStored) { if (ISVNAuthenticationManager.SSH.equals(kind) && prompt instanceof UserPasswordSSHCallback) { UserPasswordSSHCallback prompt4 = (UserPasswordSSHCallback) prompt; String userName = previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : getUserName(null, url); int port = url != null ? url.getPort() : -1; if (prompt4.promptSSH(realm, userName, port, authMayBeStored)) { String password = prompt4.getPassword(); String keyPath = prompt4.getSSHPrivateKeyPath(); String passphrase = prompt4.getSSHPrivateKeyPassphrase(); userName = getUserName(prompt4.getUsername(), url); if ("".equals(passphrase)) { passphrase = null; } port = prompt4.getSSHPort(); if (port < 0 && url != null) { port = url.getPort(); } if (port < 0) { port = 22; } boolean save = prompt4.userAllowedSave(); if (keyPath != null && !"".equals(keyPath)) { return new SVNSSHAuthentication(userName, new File(keyPath), passphrase, port, save, url, false); } else if (password != null){ return new SVNSSHAuthentication(userName, password, port, save, url, false); } } return null; } else if (ISVNAuthenticationManager.SSL.equals(kind) && SVNSSLAuthentication.isCertificatePath(realm)) { String passphrase = prompt.askQuestion(realm, "SSL Certificate Passphrase", authMayBeStored); if (passphrase != null) { return new SVNPasswordAuthentication("", passphrase, prompt.userAllowedSave(), url, false); } } else if (ISVNAuthenticationManager.SSL.equals(kind) && !SVNSSLAuthentication.isCertificatePath(realm) && (prompt instanceof UserPasswordSSLCallback)) { UserPasswordSSLCallback prompt4 = (UserPasswordSSLCallback) prompt; if (prompt4.promptSSL(realm, authMayBeStored)) { String cert = prompt4.getSSLClientCertPath(); String password = prompt4.getSSLClientCertPassword(); if (cert != null) { if ("".equals(password)) { password = null; } boolean save = prompt.userAllowedSave(); if (cert.startsWith(SVNSSLAuthentication.MSCAPI)) { String alias = null; if (cert.lastIndexOf(';') > 0) { alias = cert.substring(cert.lastIndexOf(';') + 1); } return new SVNSSLAuthentication(SVNSSLAuthentication.MSCAPI, alias, save, url, false); } SVNSSLAuthentication sslAuth = new SVNSSLAuthentication(new File(cert), password, save, url, false); sslAuth.setCertificatePath(cert); return sslAuth; } } return null; } if (ISVNAuthenticationManager.SSH.equals(kind) && previousAuth == null) { // use configuration file here? but it was already used once... String keyPath = System.getProperty("svnkit.ssh2.key", System.getProperty("javasvn.ssh2.key")); String userName = getUserName(System.getProperty("svnkit.ssh2.username", System.getProperty("javasvn.ssh2.username")), url); String passPhrase = System.getProperty("svnkit.ssh2.passphrase", System.getProperty("javasvn.ssh2.passphrase")); if (userName == null) { return null; } if (keyPath != null && previousAuth == null) { // use port number from configuration file? return new SVNSSHAuthentication(userName, new File(keyPath), passPhrase, -1, true, url, false); } // try to get password for ssh from the user. } else if(ISVNAuthenticationManager.USERNAME.equals(kind)) { String userName = previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : getUserName(null, url); if (prompt.prompt(realm, userName, authMayBeStored)) { return new SVNUserNameAuthentication(prompt.getUsername(), prompt.userAllowedSave(), url, false); } return getDefaultUserNameCredentials(userName); //TODO: prompt.prompt(String, String) is not used // if (prompt.prompt(realm, userName)) { // return new SVNUserNameAuthentication(prompt.getUsername(), false, url, false); // } // return getDefaultUserNameCredentials(userName); } else if(!ISVNAuthenticationManager.PASSWORD.equals(kind)){ return null; } String userName = previousAuth != null && previousAuth.getUserName() != null ? previousAuth.getUserName() : getUserName(null, url); // if (prompt instanceof PromptUserPassword3) { if(prompt.prompt(realm, userName, authMayBeStored)){ if (ISVNAuthenticationManager.SSH.equals(kind)) { // use default port number from configuration file (should be in previous auth). int portNumber = (previousAuth instanceof SVNSSHAuthentication) ? ((SVNSSHAuthentication) previousAuth).getPortNumber() : -1; return new SVNSSHAuthentication(prompt.getUsername(), prompt.getPassword(), portNumber, prompt.userAllowedSave(), url, false); } return new SVNPasswordAuthentication(prompt.getUsername(), prompt.getPassword(), prompt.userAllowedSave(), url, false); } //TODO: prompt.prompt(String, String) is not used // }else{ // if(prompt.prompt(realm, userName)){ // if (ISVNAuthenticationManager.SSH.equals(kind)) { // return new SVNSSHAuthentication(userName, prompt.getPassword(), -1, true, url, false); // } // return new SVNPasswordAuthentication(prompt.getUsername(), prompt.getPassword(), true, url, false); // } // } return null; } private SVNAuthentication getDefaultUserNameCredentials(String userName) { if (ADAPTER_DEFAULT_PROMPT_CLASS.equals(prompt.getClass().getName())) { // return default username, despite prompt was 'cancelled'. return new SVNUserNameAuthentication(userName, false, null, false); } return null; } public int acceptServerAuthentication(SVNURL url, String realm, Object serverAuth, boolean resultMayBeStored) { if (serverAuth instanceof X509Certificate) { serverAuth = serverAuth instanceof X509Certificate ? SVNSSLUtil.getServerCertificatePrompt((X509Certificate) serverAuth, realm, url.getHost()) : serverAuth; if (serverAuth == null) { serverAuth = "Unsupported certificate type '" + (serverAuth != null ? serverAuth.getClass().getName() : "null") + "'"; } return prompt.askTrustSSLServer(serverAuth.toString(), resultMayBeStored); } else if (prompt != null && serverAuth instanceof byte[]) { String prompt = "The ''{0}'' server''s key fingerprint is:\n{1}\n" + "If you trust this host, select ''Yes'' to add the key to the SVN cache and carry on connecting.\n" + "If you do not trust this host, select ''No'' to abandon the connection."; prompt = MessageFormat.format(prompt, new Object[]{url.getHost(), SVNSSLUtil.getFingerprint((byte[]) serverAuth, "MD5")}); if (!this.prompt.askYesNo(realm, prompt, false)) { return REJECTED; } } return ACCEPTED; } public boolean isSSLPassphrasePromtSupported() { return true; } private static String getUserName(String userName, SVNURL url) { if (userName == null || "".equals(userName.trim())) { userName = url != null ? url.getUserInfo() : null; } if (userName == null || "".equals(userName.trim())) { userName = System.getProperty("user.name"); } return userName; } }