/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.io.svn; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.auth.BasicAuthenticationManager; import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; import org.tmatesoft.svn.core.auth.SVNAuthentication; import org.tmatesoft.svn.core.auth.SVNUserNameAuthentication; import org.tmatesoft.svn.core.internal.wc.SVNErrorManager; import org.tmatesoft.svn.core.internal.wc.SVNFileUtil; import org.tmatesoft.svn.util.SVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @version 1.3 * @author TMate Software Ltd. */ public class SVNTunnelConnector extends SVNAbstractTunnelConnector { private String myTunnelSpec; private String myName; public SVNTunnelConnector(String name, String tunnelSpec) { myName = name; myTunnelSpec = tunnelSpec; } public void open(SVNRepositoryImpl repository) throws SVNException { // 1. expand tunnel spec (when env. is used). final String[] expandedTunnel = expandTunnelSpec(myName, myTunnelSpec); final List<String> sshCommand = new ArrayList<String>(); sshCommand.addAll(Arrays.asList(expandedTunnel)); // 2. create tunnel command using repo URL. String host = repository.getLocation().getHost(); if (repository.getLocation().getUserInfo() != null && !"".equals(repository.getLocation().getUserInfo())) { String username = repository.getLocation().getUserInfo(); host = username + "@" + host; } sshCommand.add(host); final String svnServeCommand; // 3. get and append --tunnel-user if needed. final ISVNAuthenticationManager authManager = repository.getAuthenticationManager(); if (authManager != null) { SVNAuthentication auth = authManager.getFirstAuthentication(ISVNAuthenticationManager.USERNAME, host, repository.getLocation()); if (auth == null) { SVNErrorManager.cancel("Authentication cancelled", SVNLogType.NETWORK); } String userName = auth.getUserName(); if (userName == null || "".equals(userName.trim())) { userName = System.getProperty("user.name"); } auth = new SVNUserNameAuthentication(userName, auth.isStorageAllowed(), repository.getLocation(), false); BasicAuthenticationManager.acknowledgeAuthentication(true, ISVNAuthenticationManager.USERNAME, host, null, auth, repository.getLocation(), authManager); svnServeCommand = "svnserve -t --tunnel-user \"" + userName + "\""; repository.setExternalUserName(userName); } else { svnServeCommand = "svnserve -t"; } sshCommand.add(svnServeCommand); SVNDebugLog.getDefaultLog().logFinest(SVNLogType.NETWORK, "tunnel command: " + sshCommand); open(repository, sshCommand.toArray(new String[sshCommand.size()])); } private static String[] expandTunnelSpec(String name, String tunnelSpec) throws SVNException { if (tunnelSpec == null || tunnelSpec.trim().length() == 0) { SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.EXTERNAL_PROGRAM, "No tunnel spec foound for ''{0}''", name); SVNErrorManager.error(err, SVNLogType.NETWORK); } tunnelSpec = tunnelSpec.trim(); int spaceIndex = tunnelSpec.indexOf(' '); String firstSegment = spaceIndex > 0 ? tunnelSpec.substring(0, spaceIndex) : tunnelSpec; String lastSegment = spaceIndex > 0 ? tunnelSpec.substring(spaceIndex).trim() : tunnelSpec; if (firstSegment.charAt(0) == '%' && firstSegment.charAt(firstSegment.length() - 1) == '%') { firstSegment = firstSegment.substring(1); firstSegment = firstSegment.substring(0, firstSegment.length() - 1); firstSegment = SVNFileUtil.getEnvironmentVariable(firstSegment); } else if (firstSegment.charAt(0) == '$') { firstSegment = firstSegment.substring(1); firstSegment = SVNFileUtil.getEnvironmentVariable(firstSegment); } else { firstSegment = null; lastSegment = null; } if (firstSegment != null) { // was expanded. tunnelSpec = firstSegment; } else if (lastSegment != null) { // was expanded with no result. tunnelSpec = lastSegment; } return tunnelSpec.split("\\s"); } public void handleExceptionOnOpen(SVNRepositoryImpl repository, SVNException exception) throws SVNException { throw exception; } }