Try writing keys to disk and encrypting them

This commit is contained in:
Matthias Pigulla 2021-02-27 20:47:41 +00:00
parent 253819f283
commit 3702096734
3 changed files with 124 additions and 65 deletions

View file

@ -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

60
dist/index.js vendored
View file

@ -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,40 +168,64 @@ 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}`;
console.log("Keys added:"); // Write private key (unencrypted!) to file
child_process.execSync('ssh-add -l', { stdio: 'inherit' }); console.log(`Write file ${keyFile}`);
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) { // Set private key passphrase
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/); 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) { if (parts == null) {
return; return;
} }
let ownerAndRepo = parts[1]; 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@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}"`);
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`); // Use IdentitiesOnly=no due to https://github.com/PowerShell/Win32-OpenSSH/issues/1550
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`); let sshConfig = `\nHost key-${keyNumber}\n`
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` + ` HostName github.com\n`
+ ` User git\n` + ` User git\n`
+ ` IdentitiesOnly no\n` + ` IdentitiesOnly yes\n`
+ ` IdentityFile ${homeSsh}/${sha256}\n`; + ` IdentityFile ${keyFile}\n`;
fs.appendFileSync(`${homeSsh}/config`, sshConfig); fs.appendFileSync(`${homeSsh}/config`, sshConfig);
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}, key file "${sha256}"`); console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
}); });
});
console.log("Keys added:");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);

View file

@ -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,40 +51,64 @@ 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}`;
console.log("Keys added:"); // Write private key (unencrypted!) to file
child_process.execSync('ssh-add -l', { stdio: 'inherit' }); console.log(`Write file ${keyFile}`);
fs.writeFileSync(keyFile, key.replace("\r\n", "\n").trim() + "\n", { mode: '600' });
child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) { // Set private key passphrase
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/); 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) { if (parts == null) {
return; return;
} }
let ownerAndRepo = parts[1]; 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@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}"`);
child_process.execSync(`git config --global --replace-all url."git@${sha256}:${ownerAndRepo}".insteadOf "https://github.com/${ownerAndRepo}"`); // Use IdentitiesOnly=no due to https://github.com/PowerShell/Win32-OpenSSH/issues/1550
child_process.execSync(`git config --global --add url."git@${sha256}:${ownerAndRepo}".insteadOf "git@github.com:${ownerAndRepo}"`); let sshConfig = `\nHost key-${keyNumber}\n`
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` + ` HostName github.com\n`
+ ` User git\n` + ` User git\n`
+ ` IdentitiesOnly no\n` + ` IdentitiesOnly yes\n`
+ ` IdentityFile ${homeSsh}/${sha256}\n`; + ` IdentityFile ${keyFile}\n`;
fs.appendFileSync(`${homeSsh}/config`, sshConfig); fs.appendFileSync(`${homeSsh}/config`, sshConfig);
console.log(`Added deploy-key mapping: Use key "${key}" for GitHub repository ${ownerAndRepo}, key file "${sha256}"`); console.log(`Added deploy-key mapping: Use key #${keyNumber} for GitHub repository ${ownerAndRepo}`);
}); });
});
console.log("Keys added:");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);