vvauth 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +26 -23
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -5,12 +5,10 @@ const os = require('os');
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const url = require('url');
|
|
8
|
-
const net = require('net');
|
|
9
8
|
const {spawn} = require('child_process');
|
|
10
9
|
|
|
11
10
|
const {parse} = require('yaml');
|
|
12
11
|
const semver = require('semver');
|
|
13
|
-
const SSHAgent = require('ssh-agent-js/client');
|
|
14
12
|
const trim = require('mout/string/trim');
|
|
15
13
|
const get = require('mout/object/get');
|
|
16
14
|
const eachLimit = require('nyks/async/eachLimit');
|
|
@@ -19,7 +17,9 @@ const walk = require('nyks/object/walk');
|
|
|
19
17
|
const request = require('nyks/http/request');
|
|
20
18
|
const drain = require('nyks/stream/drain');
|
|
21
19
|
const replaceEnv = require('nyks/string/replaceEnv');
|
|
20
|
+
const promiser = require('nyks/function/promiser');
|
|
22
21
|
|
|
22
|
+
const {OpenSSHAgent} = require('ssh2/lib/agent');
|
|
23
23
|
const debug = require('debug');
|
|
24
24
|
|
|
25
25
|
const logger = {
|
|
@@ -56,13 +56,13 @@ class vvauth {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
this.
|
|
59
|
+
this.VAULT_ADDR = this.rc.vault_addr;
|
|
60
60
|
|
|
61
|
-
if(!this.
|
|
61
|
+
if(!this.VAULT_ADDR)
|
|
62
62
|
throw `Invalid vault remote`;
|
|
63
63
|
|
|
64
64
|
this.VAULT_TOKEN = process.env.VAULT_TOKEN;
|
|
65
|
-
console.error("vauth bound to '%s'", this.
|
|
65
|
+
console.error("vauth bound to '%s'", this.VAULT_ADDR);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
async connect() {
|
|
@@ -90,7 +90,7 @@ class vvauth {
|
|
|
90
90
|
_publish_env(env) {
|
|
91
91
|
let cmds = [];
|
|
92
92
|
for(let [k, v] of Object.entries(env)) {
|
|
93
|
-
cmds.push(`export ${k}
|
|
93
|
+
cmds.push(`export ${k}=${shellEscape(v)}`);
|
|
94
94
|
cmds.push(`echo export ${k}=[redacted] >&2`);
|
|
95
95
|
}
|
|
96
96
|
process.stdout.write(cmds.join("\n") + "\n");
|
|
@@ -136,7 +136,7 @@ class vvauth {
|
|
|
136
136
|
async env(source = false) {
|
|
137
137
|
let {profile} = await this._get_profile();
|
|
138
138
|
|
|
139
|
-
let env = {VAULT_TOKEN : this.VAULT_TOKEN}, secrets = {},
|
|
139
|
+
let env = {VAULT_TOKEN : this.VAULT_TOKEN, VAULT_ADDR : this.VAULT_ADDR}, secrets = {},
|
|
140
140
|
{git, map = {}, paths, path : mount = "secrets"} = this.rc.env || {};
|
|
141
141
|
|
|
142
142
|
if(git) {
|
|
@@ -166,7 +166,7 @@ class vvauth {
|
|
|
166
166
|
|
|
167
167
|
|
|
168
168
|
async _read(mount, secret_path) {
|
|
169
|
-
let remote_url = `${trim(this.
|
|
169
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/${mount}/data/${trim(secret_path, '/')}`;
|
|
170
170
|
let query = {...url.parse(remote_url), headers : {'x-vault-token' : this.VAULT_TOKEN}, expect : 200};
|
|
171
171
|
let res = await request(query);
|
|
172
172
|
return get(JSON.parse(String(await drain(res))), 'data.data');
|
|
@@ -174,33 +174,32 @@ class vvauth {
|
|
|
174
174
|
|
|
175
175
|
async _login_vault_ssh({path = 'ssh', role}) {
|
|
176
176
|
logger.info("Trying to auth as '%s'", role);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
let agent = new
|
|
180
|
-
let keys =
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
let agent = new OpenSSHAgent(process.env.SSH_AUTH_SOCK);
|
|
180
|
+
let keys = await promiser(chain => agent.getIdentities(chain));
|
|
181
|
+
|
|
181
182
|
|
|
182
183
|
let token;
|
|
183
|
-
await eachLimit(keys, 1, async (
|
|
184
|
+
await eachLimit(keys, 1, async (pubKey) => {
|
|
184
185
|
if(token)
|
|
185
186
|
return;
|
|
186
187
|
|
|
187
|
-
let remote_url = `${trim(this.
|
|
188
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/auth/${path}/nonce`;
|
|
188
189
|
let query = {...url.parse(remote_url), json : true};
|
|
189
190
|
let res = await request(query);
|
|
190
191
|
let {data : {nonce}} = JSON.parse(String(await drain(res)));
|
|
191
192
|
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
|
|
193
|
+
const signature = (await promiser(chain => agent.sign(pubKey, Buffer.from(nonce), {}, chain))).toString('base64');
|
|
194
|
+
const public_key = pubKey.type + ' ' + pubKey.getPublicSSH().toString('base64');
|
|
195
195
|
const payload = {public_key, role, nonce : Buffer.from(nonce).toString('base64'), signature};
|
|
196
196
|
try {
|
|
197
197
|
token = await this._login_vault(path, payload);
|
|
198
198
|
} catch(err) {
|
|
199
|
-
logger.debug("ssh : invalid challenge for public key", comment);
|
|
199
|
+
logger.debug("ssh : invalid challenge for public key", pubKey.comment);
|
|
200
200
|
}
|
|
201
201
|
});
|
|
202
202
|
|
|
203
|
-
sock.destroy();
|
|
204
203
|
|
|
205
204
|
if(!token)
|
|
206
205
|
throw `Could not login to vault`;
|
|
@@ -227,7 +226,7 @@ class vvauth {
|
|
|
227
226
|
}
|
|
228
227
|
|
|
229
228
|
async _lookup_token(token) {
|
|
230
|
-
let remote_url = `${trim(this.
|
|
229
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/auth/token/lookup-self`;
|
|
231
230
|
let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 200};
|
|
232
231
|
let res = await request(query);
|
|
233
232
|
let response = JSON.parse(await drain(res)).data;
|
|
@@ -235,14 +234,14 @@ class vvauth {
|
|
|
235
234
|
}
|
|
236
235
|
|
|
237
236
|
async _lookup_identity(token, id) {
|
|
238
|
-
let remote_url = `${trim(this.
|
|
237
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/identity/entity/id/${id}`;
|
|
239
238
|
let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 200};
|
|
240
239
|
let res = await request(query);
|
|
241
240
|
return JSON.parse(String(await drain(res))).data;
|
|
242
241
|
}
|
|
243
242
|
|
|
244
243
|
async _update_identity(token, id, payload) {
|
|
245
|
-
let remote_url = `${trim(this.
|
|
244
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/identity/entity/id/${id}`;
|
|
246
245
|
let query = {...url.parse(remote_url), headers : {'x-vault-token' : token}, expect : 204, json : true};
|
|
247
246
|
await request(query, payload);
|
|
248
247
|
return payload;
|
|
@@ -251,7 +250,7 @@ class vvauth {
|
|
|
251
250
|
|
|
252
251
|
|
|
253
252
|
async _login_vault(path, payload) {
|
|
254
|
-
let remote_url = `${trim(this.
|
|
253
|
+
let remote_url = `${trim(this.VAULT_ADDR, '/')}/v1/auth/${path}/login`;
|
|
255
254
|
let query = {...url.parse(remote_url), json : true};
|
|
256
255
|
let res = await request(query, payload);
|
|
257
256
|
let response = String(await drain(res));
|
|
@@ -266,6 +265,10 @@ class vvauth {
|
|
|
266
265
|
|
|
267
266
|
}
|
|
268
267
|
|
|
268
|
+
const shellEscape = (arg) => {
|
|
269
|
+
return arg.replace(/([$!'"();`*?{}[\]<>&%#~@\\ ])/g, '\\$1');
|
|
270
|
+
};
|
|
271
|
+
|
|
269
272
|
//ensure module is called directly, i.e. not required
|
|
270
273
|
if(module.parent === null)
|
|
271
274
|
require('cnyks/lib/bundle')(vvauth);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vvauth",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Vault Auth helper",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"cnyks": "^3.0.6",
|
|
16
16
|
"debug": "^4.3.4",
|
|
17
17
|
"mout": "^1.0.0",
|
|
18
|
-
"nyks": "^6.
|
|
18
|
+
"nyks": "^6.15.0",
|
|
19
19
|
"semver": "^7.5.4",
|
|
20
|
-
"
|
|
20
|
+
"ssh2": "^1.16.0",
|
|
21
21
|
"yaml": "^2.6.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|