use of jetbrains.buildServer.ssh.TeamCitySshKey in project teamcity-git by JetBrains.
the class FetchCommandImpl method getTeamCityPrivateKey.
private File getTeamCityPrivateKey(@NotNull AuthSettings authSettings) throws VcsException {
if (authSettings.getAuthMethod() != AuthenticationMethod.TEAMCITY_SSH_KEY)
return null;
String keyId = authSettings.getTeamCitySshKeyId();
if (keyId == null)
return null;
VcsRoot root = authSettings.getRoot();
if (root == null)
return null;
TeamCitySshKey privateKey = mySshKeyManager.getKey(root);
if (privateKey == null)
return null;
try {
File privateKeyFile = FileUtil.createTempFile("private", "key");
FileUtil.writeToFile(privateKeyFile, privateKey.getPrivateKey());
return privateKeyFile;
} catch (IOException e) {
throw new VcsException(e);
}
}
use of jetbrains.buildServer.ssh.TeamCitySshKey in project teamcity-git by JetBrains.
the class SshAuthenticationTest method do_ssh_test.
private void do_ssh_test(boolean nativeOperationsEnabled, boolean useSshAskPass, @NotNull String urlFormat, @NotNull String sshdConfig, @Nullable TeamCitySshKey tcKey, @Nullable String publicKey, @NotNull VcsRootConfigurator builder, boolean ignoreKnownHosts) throws Exception {
if (!nativeOperationsEnabled) {
JSchConfigInitializer.initJSchConfig(JSch.class);
}
final File pub_key = publicKey == null ? null : dataFile(publicKey);
ssh_test(pub_key, sshdConfig, container -> {
setInternalProperty("teamcity.git.nativeOperationsEnabled", String.valueOf(nativeOperationsEnabled));
setInternalProperty("teamcity.git.useSshAskPas", String.valueOf(useSshAskPass));
setInternalProperty("teamcity.git.debugNativeGit", "true");
final ServerPaths serverPaths = new ServerPaths(myTempFiles.createTempDir().getAbsolutePath());
final ServerPluginConfig config = new PluginConfigBuilder(serverPaths).build();
final VcsRootSshKeyManager keyManager = r -> tcKey;
final TransportFactoryImpl transportFactory = new TransportFactoryImpl(config, keyManager);
final GitRepoOperationsImpl repoOperations = new GitRepoOperationsImpl(config, transportFactory, keyManager, new FetchCommandImpl(config, transportFactory, new FetcherProperties(config), keyManager));
final MirrorManagerImpl mirrorManager = new MirrorManagerImpl(config, new HashCalculatorImpl(), new RemoteRepositoryUrlInvestigatorImpl());
final RepositoryManagerImpl repositoryManager = new RepositoryManagerImpl(config, mirrorManager);
final String repoUrl = String.format(urlFormat, container.getContainerIpAddress(), container.getMappedPort(22));
final GitVcsRoot gitRoot = new GitVcsRoot(mirrorManager, builder.config(VcsRootBuilder.vcsRoot().withFetchUrl(repoUrl).withIgnoreKnownHosts(ignoreKnownHosts)).build(), new URIishHelperImpl());
JSch.setLogger(JSchLoggers.STD_DEBUG_JSCH_LOGGER);
// here we test some git operations
final URIish fetchUrl = new URIish(repoUrl);
final Repository db = repositoryManager.openRepository(fetchUrl);
final Map<String, Ref> refs = repoOperations.lsRemoteCommand(repoUrl).lsRemote(db, gitRoot, new FetchSettings(gitRoot.getAuthSettings()));
assertContains(refs.keySet(), "refs/pull/1");
final StringBuilder progress = new StringBuilder();
final List<RefSpec> refSpecs = refs.keySet().stream().map(r -> new RefSpec().setSourceDestination(r, r).setForceUpdate(true)).collect(Collectors.toList());
repoOperations.fetchCommand(repoUrl).fetch(db, fetchUrl, new FetchSettings(gitRoot.getAuthSettings(), new GitProgress() {
@Override
public void reportProgress(@NotNull final String p) {
progress.append(p).append("\n");
}
@Override
public void reportProgress(final float p, @NotNull final String stage) {
if (p < 0) {
progress.append(stage).append("\n");
} else {
int percents = (int) Math.floor(p * 100);
progress.append(stage).append(" ").append(percents).append("%");
}
}
}, refSpecs));
if (nativeOperationsEnabled) {
assertContains(progress.toString(), "* [new ref] refs/pull/1 -> refs/pull/1");
} else {
assertContains(progress.toString(), "update ref remote name: refs/pull/1, local name: refs/pull/1, old object id: 0000000000000000000000000000000000000000, new object id: b896070465af79121c9a4eb5300ecff29453c164, result: NEW");
}
final GitVcsSupport vcsSupport = GitSupportBuilder.gitSupport().withServerPaths(serverPaths).withPluginConfig(config).withTransportFactory(transportFactory).build();
repoOperations.tagCommand(vcsSupport, repoUrl).tag(vcsSupport.createContext(gitRoot.getOriginalRoot(), "tag"), "test_tag", "b896070465af79121c9a4eb5300ecff29453c164");
assertContains(repoOperations.lsRemoteCommand(repoUrl).lsRemote(db, gitRoot, new FetchSettings(gitRoot.getAuthSettings())).keySet(), "refs/tags/test_tag");
});
}
use of jetbrains.buildServer.ssh.TeamCitySshKey in project teamcity-git by JetBrains.
the class SshAuthenticationTest method ssh_git_ecdsa_encrypted_uploaded_key.
@Test(dataProvider = "true,false")
public void ssh_git_ecdsa_encrypted_uploaded_key(boolean nativeOperationsEnabled) throws Exception {
final File key = dataFile("keys/id_ecdsa_encrypted");
do_ssh_test(nativeOperationsEnabled, true, "ssh://git@%s:%s/home/git/repo.git", "", new TeamCitySshKey("test_key", Files.readAllBytes(key.toPath()), true), "keys/id_ecdsa_encrypted.pub", b -> b.withAuthMethod(AuthenticationMethod.TEAMCITY_SSH_KEY).withTeamCitySshKey("test_key").withPassphrase("12345"));
}
use of jetbrains.buildServer.ssh.TeamCitySshKey in project teamcity-git by JetBrains.
the class GitCommandLine method getUploadedPrivateKey.
@NotNull
private File getUploadedPrivateKey(@NotNull AuthSettings authSettings) throws Exception {
final String keyId = authSettings.getTeamCitySshKeyId();
final VcsRoot root = authSettings.getRoot();
if (keyId == null || root == null || mySshKeyManager == null) {
final String msg = "Failed to locate uploaded SSH key " + keyId + " for vcs root %s " + (mySshKeyManager == null ? ": null ssh key manager" : "");
Loggers.VCS.warn(String.format(msg, LogUtil.describe(root)));
throw new VcsException(String.format(msg, root == null ? null : root.getName()));
}
final TeamCitySshKey key = mySshKeyManager.getKey(root);
if (key == null) {
throw new VcsException("Failed to locate uploaded SSH key " + keyId + " for vcs root " + root.getName());
}
final File privateKey = createTmpKeyFile();
addPostAction(() -> FileUtil.delete(privateKey));
FileUtil.writeFileAndReportErrors(privateKey, new String(key.getPrivateKey()));
return privateKey;
}
use of jetbrains.buildServer.ssh.TeamCitySshKey in project teamcity-git by JetBrains.
the class GitUrlSupport method convertToVcsRootProperties.
@Nullable
public Map<String, String> convertToVcsRootProperties(@NotNull VcsUrl url, @NotNull VcsOperationContext operationContext) throws VcsException {
String scmName = getMavenScmName(url);
if (// some other scm provider
scmName != null && !"git".equals(scmName) && !"ssh".equals(scmName))
return null;
String fetchUrl = getFetchUrl(url);
URIish uri = parseURIish(fetchUrl);
if (fetchUrl.startsWith("https://") && !fetchUrl.endsWith(".git")) {
VcsHostingRepo gitlabRepo = WellKnownHostingsUtil.getGitlabRepo(uri);
if (gitlabRepo != null) {
// for GitLab we need to add .git suffix to the fetch URL, otherwise, for some reason JGit can't work with this repository (although regular git command works)
fetchUrl = fetchUrl + ".git";
uri = parseURIish(fetchUrl);
}
}
Map<String, String> props = new HashMap<>(myGitSupport.getDefaultVcsProperties());
props.put(Constants.FETCH_URL, fetchUrl);
props.putAll(getAuthSettings(url, uri));
VcsHostingRepo ghRepo = WellKnownHostingsUtil.getGitHubRepo(uri);
if (ghRepo != null)
refineGithubSettings(ghRepo, props);
int numSshKeysTried = 0;
final SProject curProject = myProjectManager == null ? null : myProjectManager.findProjectById(operationContext.getCurrentProjectId());
if (AuthenticationMethod.PRIVATE_KEY_DEFAULT.toString().equals(props.get(Constants.AUTH_METHOD)) && fetchUrl.endsWith(".git") && curProject != null) {
// SSH access, before using the default private key which may not be accessible on the agent,
// let's iterate over all SSH keys of the current project, maybe we'll find a working one
ServerSshKeyManager serverSshKeyManager = getSshKeyManager();
if (serverSshKeyManager != null) {
for (TeamCitySshKey key : serverSshKeyManager.getKeys(curProject)) {
// don't know password, so can't use it
if (key.isEncrypted())
continue;
Map<String, String> propsCopy = new HashMap<>(props);
propsCopy.put(Constants.AUTH_METHOD, AuthenticationMethod.TEAMCITY_SSH_KEY.toString());
propsCopy.put(VcsRootSshKeyManager.VCS_ROOT_TEAMCITY_SSH_KEY_NAME, key.getName());
try {
numSshKeysTried++;
return testConnection(propsCopy, curProject);
} catch (VcsException e) {
if (isBranchRelatedError(e))
throw e;
}
}
}
// could not find any valid keys, proceed with default SSH key
try {
return testConnection(props, curProject);
} catch (VcsException e) {
if (isBranchRelatedError(e))
throw e;
String message = "Could not connect to the Git repository by SSH protocol.";
if (numSshKeysTried > 0) {
message += " Tried " + numSshKeysTried + " SSH " + StringUtil.pluralize("key", numSshKeysTried) + " accessible from the current project.";
} else {
message += " Could not find an SSH key in the current project which would work with this Git repository.";
}
throw new VcsException(message + " Error message: " + e.getMessage(), e);
}
}
final boolean defaultBranchKnown = props.get(Constants.BRANCH_NAME) != null;
if (defaultBranchKnown) {
// git protocol, or git scm provider
if ("git".equals(scmName) || "git".equals(uri.getScheme()) || fetchUrl.endsWith(".git"))
return props;
}
// not SSH or URL does not end with .git, still try to connect just for the case
try {
return testConnection(props, curProject);
} catch (VcsException e) {
if (isBranchRelatedError(e) || GitServerUtil.isAuthError(e) || fetchUrl.toLowerCase().contains("git"))
throw e;
// probably not git
Loggers.VCS.infoAndDebugDetails("Failed to recognize " + url.getUrl() + " as a git repository", e);
return null;
}
}
Aggregations