Try writing keys to disk and encrypting them
This commit is contained in:
parent
253819f283
commit
3702096734
3 changed files with 124 additions and 65 deletions
21
.github/workflows/demo.yml
vendored
21
.github/workflows/demo.yml
vendored
|
@ -58,10 +58,21 @@ jobs:
|
||||||
${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
|
${{ secrets.MPDUDE_TEST_1_DEPLOY_KEY }}
|
||||||
${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
|
${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}
|
||||||
- run: |
|
- run: |
|
||||||
cat > ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 <<< "${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}"
|
cat ~/.ssh/config
|
||||||
ssh-keygen -p -f ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 -N secret-passphrase
|
ls -alh ~/.ssh
|
||||||
eval `ssh-agent`
|
|
||||||
echo "secret-passphrase" | ssh-add ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9
|
|
||||||
ssh-add -L
|
|
||||||
git clone git@github.com:mpdude/test-2.git test-2-git
|
git clone git@github.com:mpdude/test-2.git test-2-git
|
||||||
|
|
||||||
|
# git clone https://github.com/mpdude/test-1.git test-1-http
|
||||||
|
# git clone git@github.com:mpdude/test-1.git test-1-git
|
||||||
|
# git clone ssh://git@github.com/mpdude/test-1.git test-1-git-ssh
|
||||||
|
# git clone https://github.com/mpdude/test-2.git test-2-http
|
||||||
|
|
||||||
|
# git clone ssh://git@github.com/mpdude/test-2.git test-2-git-ssh
|
||||||
|
|
||||||
|
# cat > ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 <<< "${{ secrets.MPDUDE_TEST_2_DEPLOY_KEY }}"
|
||||||
|
# ssh-keygen -p -f ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9 -N secret-passphrase
|
||||||
|
# eval `ssh-agent`
|
||||||
|
# echo "secret-passphrase" | ssh-add ~/.ssh/5965bf89ab6e2900262e3f6802dfb4d65cb0de539d0fbb97d381e7130a4ba7e9
|
||||||
|
# ssh-add -L
|
||||||
|
# git clone git@github.com:mpdude/test-2.git test-2-git
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
84
dist/index.js
vendored
84
dist/index.js
vendored
|
@ -119,7 +119,7 @@ const core = __webpack_require__(470);
|
||||||
const child_process = __webpack_require__(129);
|
const child_process = __webpack_require__(129);
|
||||||
const fs = __webpack_require__(747);
|
const fs = __webpack_require__(747);
|
||||||
const os = __webpack_require__(87);
|
const os = __webpack_require__(87);
|
||||||
const crypto = __webpack_require__(417);
|
const token = __webpack_require__(417).randomBytes(64).toString('hex');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const privateKey = core.getInput('ssh-private-key');
|
const privateKey = core.getInput('ssh-private-key');
|
||||||
|
@ -168,41 +168,65 @@ try {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Adding private key to agent");
|
console.log("Adding private keys to agent");
|
||||||
|
var keyNumber = 0;
|
||||||
|
|
||||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||||
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
|
++keyNumber;
|
||||||
|
let keyFile = `${homeSsh}/key_${keyNumber}`;
|
||||||
|
|
||||||
|
// Write private key (unencrypted!) to file
|
||||||
|
console.log(`Write file ${keyFile}`);
|
||||||
|
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
|
||||||
|
|
||||||
|
// Set private key passphrase
|
||||||
|
let output = '';
|
||||||
|
try {
|
||||||
|
console.log(`Set passphrase on ${keyFile}`);
|
||||||
|
output = child_process.execFileSync('ssh-keygen', ['-p', '-f', keyFile, '-N', token], { stdio: 'inherit' });
|
||||||
|
} catch (exception) {
|
||||||
|
fs.unlinkSync(keyFile);
|
||||||
|
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load key into agent
|
||||||
|
console.log('Load key');
|
||||||
|
//let sshAdd = child_process.execSync(`echo "${token}" | ssh-add "${keyFile}"`, { stdio: 'inherit' });
|
||||||
|
let sshAdd = child_process.execFileSync('ssh-add', [keyFile], { stdio: 'inherit' });
|
||||||
|
// input: token + "\n", stdio: ['pipe', 'inherit', 'inherit'] });
|
||||||
|
//sshAdd.stdin.write(token + "\n");
|
||||||
|
//sshAdd.stdin.end();
|
||||||
|
|
||||||
|
output.toString().split(/\r?\n/).forEach(function(key) {
|
||||||
|
let parts = key.match(/^Key has comment '.*\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+?)(?=\.git|\s|\')/);
|
||||||
|
|
||||||
|
if (parts == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ownerAndRepo = parts[1];
|
||||||
|
|
||||||
|
child_process.execSync(`git config --global --replace-all url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||||
|
|
||||||
|
// Use IdentitiesOnly=no due to https://github.com/PowerShell/Win32-OpenSSH/issues/1550
|
||||||
|
let sshConfig = `\nHost key-${keyNumber}\n`
|
||||||
|
+ ` HostName github.com\n`
|
||||||
|
+ ` User git\n`
|
||||||
|
+ ` IdentitiesOnly yes\n`
|
||||||
|
+ ` IdentityFile ${keyFile}\n`;
|
||||||
|
|
||||||
|
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||||
|
|
||||||
|
console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Keys added:");
|
console.log("Keys added:");
|
||||||
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||||
|
|
||||||
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
|
||||||
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
|
|
||||||
|
|
||||||
if (parts == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ownerAndRepo = parts[1];
|
|
||||||
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
|
||||||
|
|
||||||
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' });
|
|
||||||
|
|
||||||
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
|
||||||
|
|
||||||
let sshConfig = `\nHost ${sha256}\n`
|
|
||||||
+ ` HostName github.com\n`
|
|
||||||
+ ` User git\n`
|
|
||||||
+ ` IdentitiesOnly no\n`
|
|
||||||
+ ` IdentityFile ${homeSsh}/${sha256}\n`;
|
|
||||||
|
|
||||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
|
||||||
|
|
||||||
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}, key file "${sha256}"`);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
|
84
index.js
84
index.js
|
@ -2,7 +2,7 @@ const core = require('@actions/core');
|
||||||
const child_process = require('child_process');
|
const child_process = require('child_process');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const crypto = require('crypto');
|
const token = require('crypto').randomBytes(64).toString('hex');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const privateKey = core.getInput('ssh-private-key');
|
const privateKey = core.getInput('ssh-private-key');
|
||||||
|
@ -51,41 +51,65 @@ try {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Adding private key to agent");
|
console.log("Adding private keys to agent");
|
||||||
|
var keyNumber = 0;
|
||||||
|
|
||||||
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
privateKey.split(/(?=-----BEGIN)/).forEach(function(key) {
|
||||||
child_process.execSync('ssh-add -', { input: key.trim() + "\n" });
|
++keyNumber;
|
||||||
|
let keyFile = `${homeSsh}/key_${keyNumber}`;
|
||||||
|
|
||||||
|
// Write private key (unencrypted!) to file
|
||||||
|
console.log(`Write file ${keyFile}`);
|
||||||
|
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
|
||||||
|
|
||||||
|
// Set private key passphrase
|
||||||
|
let output = '';
|
||||||
|
try {
|
||||||
|
console.log(`Set passphrase on ${keyFile}`);
|
||||||
|
output = child_process.execFileSync('ssh-keygen', ['-p', '-f', keyFile, '-N', token], { stdio: 'inherit' });
|
||||||
|
} catch (exception) {
|
||||||
|
fs.unlinkSync(keyFile);
|
||||||
|
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load key into agent
|
||||||
|
console.log('Load key');
|
||||||
|
//let sshAdd = child_process.execSync(`echo "${token}" | ssh-add "${keyFile}"`, { stdio: 'inherit' });
|
||||||
|
let sshAdd = child_process.execFileSync('ssh-add', [keyFile], { stdio: 'inherit' });
|
||||||
|
// input: token + "\n", stdio: ['pipe', 'inherit', 'inherit'] });
|
||||||
|
//sshAdd.stdin.write(token + "\n");
|
||||||
|
//sshAdd.stdin.end();
|
||||||
|
|
||||||
|
output.toString().split(/\r?\n/).forEach(function(key) {
|
||||||
|
let parts = key.match(/^Key has comment '.*\bgithub\.com[:/]([_.a-z0-9-]+\/[_.a-z0-9-]+?)(?=\.git|\s|\')/);
|
||||||
|
|
||||||
|
if (parts == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ownerAndRepo = parts[1];
|
||||||
|
|
||||||
|
child_process.execSync(`git config --global --replace-all url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
||||||
|
child_process.execSync(`git config --global --add url."git@key-${keyNumber}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
||||||
|
|
||||||
|
// Use IdentitiesOnly=no due to https://github.com/PowerShell/Win32-OpenSSH/issues/1550
|
||||||
|
let sshConfig = `\nHost key-${keyNumber}\n`
|
||||||
|
+ ` HostName github.com\n`
|
||||||
|
+ ` User git\n`
|
||||||
|
+ ` IdentitiesOnly yes\n`
|
||||||
|
+ ` IdentityFile ${keyFile}\n`;
|
||||||
|
|
||||||
|
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
||||||
|
|
||||||
|
console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Keys added:");
|
console.log("Keys added:");
|
||||||
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
|
||||||
|
|
||||||
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
|
|
||||||
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
|
|
||||||
|
|
||||||
if (parts == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ownerAndRepo = parts[1];
|
|
||||||
let sha256 = crypto.createHash('sha256').update(key).digest('hex');
|
|
||||||
|
|
||||||
fs.writeFileSync(`${homeSsh}/${sha256}`, key + "\n", { mode: '600' });
|
|
||||||
|
|
||||||
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`);
|
|
||||||
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "ssh://git@github.com/${ownerAndRepo}"`);
|
|
||||||
|
|
||||||
let sshConfig = `\nHost ${sha256}\n`
|
|
||||||
+ ` HostName github.com\n`
|
|
||||||
+ ` User git\n`
|
|
||||||
+ ` IdentitiesOnly no\n`
|
|
||||||
+ ` IdentityFile ${homeSsh}/${sha256}\n`;
|
|
||||||
|
|
||||||
fs.appendFileSync(`${homeSsh}/config`, sshConfig);
|
|
||||||
|
|
||||||
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}, key file "${sha256}"`);
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error.message);
|
core.setFailed(error.message);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue