mirror of
https://github.com/webfactory/ssh-agent.git
synced 2024-11-25 02:18:03 +00:00
37d5edd102
Added support for GitHub Enterprise servers by loosening the restrictions on the hostname portion of the deploy key comment being "github.com" to any hostname and then using that hostname in the rest of the config. Adjusted the regex to match the end of the line since the comment portion is at the end. fixes #934
100 lines
4.9 KiB
JavaScript
100 lines
4.9 KiB
JavaScript
const core = require('@actions/core');
|
|
const child_process = require('child_process');
|
|
const fs = require('fs');
|
|
const crypto = require('crypto');
|
|
const { homePath, sshAgentCmdDefault, sshAddCmdDefault, gitCmdDefault } = require('./paths.js');
|
|
|
|
try {
|
|
const privateKey = core.getInput('ssh-private-key');
|
|
const logPublicKey = core.getBooleanInput('log-public-key', {default: true});
|
|
|
|
const sshAgentCmdInput = core.getInput('ssh-agent-cmd');
|
|
const sshAddCmdInput = core.getInput('ssh-add-cmd');
|
|
const gitCmdInput = core.getInput('git-cmd');
|
|
|
|
const sshAgentCmd = sshAgentCmdInput ? sshAgentCmdInput : sshAgentCmdDefault;
|
|
const sshAddCmd = sshAddCmdInput ? sshAddCmdInput : sshAddCmdDefault;
|
|
const gitCmd = gitCmdInput ? gitCmdInput : gitCmdDefault;
|
|
|
|
if (!privateKey) {
|
|
core.setFailed("The ssh-private-key argument is empty. Maybe the secret has not been configured, or you are using a wrong secret name in your workflow file.");
|
|
|
|
return;
|
|
}
|
|
|
|
const homeSsh = homePath + '/.ssh';
|
|
|
|
console.log(`Adding GitHub.com keys to ${homeSsh}/known_hosts`);
|
|
|
|
fs.mkdirSync(homeSsh, { recursive: true });
|
|
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\n');
|
|
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\n');
|
|
fs.appendFileSync(`${homeSsh}/known_hosts`, '\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==\n');
|
|
|
|
console.log("Starting ssh-agent");
|
|
|
|
const authSock = core.getInput('ssh-auth-sock');
|
|
const sshAgentArgs = (authSock && authSock.length > 0) ? ['-a', authSock] : [];
|
|
|
|
// Extract auth socket path and agent pid and set them as job variables
|
|
child_process.execFileSync(sshAgentCmd, sshAgentArgs).toString().split("\n").forEach(function(line) {
|
|
const matches = /^(SSH_AUTH_SOCK|SSH_AGENT_PID)=(.*); export \1/.exec(line);
|
|
|
|
if (matches && matches.length > 0) {
|
|
// This will also set process.env accordingly, so changes take effect for this script
|
|
core.exportVariable(matches[1], matches[2])
|
|
console.log(`${matches[1]}=${matches[2]}`);
|
|
}
|
|
});
|
|
|
|
console.log("Adding private key(s) to agent");
|
|
|
|
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
|
child_process.execFileSync(sshAddCmd, ['-'], { input: key.trim() + "\n" });
|
|
});
|
|
|
|
console.log("Key(s) added:");
|
|
|
|
child_process.execFileSync(sshAddCmd, ['-l'], { stdio: 'inherit' });
|
|
|
|
console.log('Configuring deployment key(s)');
|
|
|
|
child_process.execFileSync(sshAddCmd, ['-L']).toString().trim().split(/\r?\n/).forEach(function(key) {
|
|
const parts = key.match(/\b([\w.]+)[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+)$/i);
|
|
|
|
if (!parts) {
|
|
if (logPublicKey) {
|
|
console.log(`Comment for (public) key '${key}' does not match GitHub URL pattern. Not treating it as a GitHub deploy key.`);
|
|
}
|
|
return;
|
|
}
|
|
|
|
const sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
|
const githubHost = parts[1];
|
|
const ownerAndRepo = parts[2].replace(/\.git$/, '');
|
|
|
|
fs.writeFileSync(`${homeSsh}/key-${sha256}`, key + "\n", { mode: '600' });
|
|
|
|
child_process.execSync(`${gitCmd} config --global --replace-all url."git@key-${sha256}.${githubHost}:${ownerAndRepo}".insteadOf "https://${githubHost}/${ownerAndRepo}"`);
|
|
child_process.execSync(`${gitCmd} config --global --add url."git@key-${sha256}.${githubHost}:${ownerAndRepo}".insteadOf "git@${githubHost}:${ownerAndRepo}"`);
|
|
child_process.execSync(`${gitCmd} config --global --add url."git@key-${sha256}.${githubHost}:${ownerAndRepo}".insteadOf "ssh://git@${githubHost}/${ownerAndRepo}"`);
|
|
|
|
const sshConfig = `\nHost key-${sha256}.${githubHost}\n`
|
|
+ ` HostName ${githubHost}\n`
|
|
+ ` IdentityFile ${homeSsh}/key-${sha256}\n`
|
|
+ ` IdentitiesOnly yes\n`;
|
|
|
|
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
|
|
|
console.log(`Added deploy-key mapping: Use identity '${homeSsh}/key-${sha256}' for GitHub repository ${ownerAndRepo}`);
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
if (error.code == 'ENOENT') {
|
|
console.log(`The '${error.path}' executable could not be found. Please make sure it is on your PATH and/or the necessary packages are installed.`);
|
|
console.log(`PATH is set to: ${process.env.PATH}`);
|
|
}
|
|
|
|
core.setFailed(error.message);
|
|
}
|