@awcp/transport-sshfs 0.0.0-dev-202601300724 → 0.0.0-dev-202601301521

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.
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AWCP SSHFS Transport Setup CLI
4
+ *
5
+ * Configures SSH certificate authentication for AWCP.
6
+ *
7
+ * Usage:
8
+ * npx @awcp/transport-sshfs setup # Check and guide
9
+ * npx @awcp/transport-sshfs setup --auto # Auto-configure (needs sudo)
10
+ * npx @awcp/transport-sshfs setup --check # Check only
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
@@ -0,0 +1,286 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AWCP SSHFS Transport Setup CLI
4
+ *
5
+ * Configures SSH certificate authentication for AWCP.
6
+ *
7
+ * Usage:
8
+ * npx @awcp/transport-sshfs setup # Check and guide
9
+ * npx @awcp/transport-sshfs setup --auto # Auto-configure (needs sudo)
10
+ * npx @awcp/transport-sshfs setup --check # Check only
11
+ */
12
+ import { spawn, execSync } from 'node:child_process';
13
+ import { access, mkdir, readFile, constants } from 'node:fs/promises';
14
+ import { join } from 'node:path';
15
+ import { homedir, platform } from 'node:os';
16
+ import * as net from 'node:net';
17
+ const CA_KEY_PATH = join(homedir(), '.awcp', 'ca');
18
+ const SSHD_CONFIG_PATH = '/etc/ssh/sshd_config';
19
+ /**
20
+ * Print colored output
21
+ */
22
+ function print(message) {
23
+ console.log(message);
24
+ }
25
+ function printStatus(name, status, message) {
26
+ const icon = status === 'ok' ? '✓' : status === 'missing' ? '✗' : '!';
27
+ const color = status === 'ok' ? '\x1b[32m' : status === 'missing' ? '\x1b[31m' : '\x1b[33m';
28
+ console.log(` ${color}[${icon}]\x1b[0m ${name.padEnd(20)} ${message}`);
29
+ }
30
+ /**
31
+ * Check if a command exists
32
+ */
33
+ async function commandExists(cmd) {
34
+ try {
35
+ execSync(`which ${cmd}`, { stdio: 'ignore' });
36
+ return true;
37
+ }
38
+ catch {
39
+ return false;
40
+ }
41
+ }
42
+ /**
43
+ * Check if sshd is running
44
+ */
45
+ /**
46
+ * Check if sshd is running by trying to connect to port 22
47
+ */
48
+ async function isSshdRunning() {
49
+ return new Promise((resolve) => {
50
+ const socket = new net.Socket();
51
+ socket.setTimeout(2000);
52
+ socket.on('connect', () => {
53
+ socket.destroy();
54
+ resolve(true);
55
+ });
56
+ socket.on('timeout', () => {
57
+ socket.destroy();
58
+ resolve(false);
59
+ });
60
+ socket.on('error', () => {
61
+ resolve(false);
62
+ });
63
+ socket.connect(22, 'localhost');
64
+ });
65
+ }
66
+ /**
67
+ * Check if sshd_config has TrustedUserCAKeys configured
68
+ */
69
+ async function isSshdConfigured() {
70
+ try {
71
+ const content = await readFile(SSHD_CONFIG_PATH, 'utf-8');
72
+ const caKeyPub = `${CA_KEY_PATH}.pub`;
73
+ return content.includes(`TrustedUserCAKeys`) && content.includes(caKeyPub);
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ /**
80
+ * Check if CA key exists
81
+ */
82
+ async function caKeyExists() {
83
+ try {
84
+ await access(CA_KEY_PATH, constants.R_OK);
85
+ return true;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
91
+ /**
92
+ * Generate CA key pair
93
+ */
94
+ async function generateCaKey() {
95
+ const caDir = join(CA_KEY_PATH, '..');
96
+ await mkdir(caDir, { recursive: true, mode: 0o700 });
97
+ return new Promise((resolve, reject) => {
98
+ const proc = spawn('ssh-keygen', [
99
+ '-t', 'ed25519',
100
+ '-f', CA_KEY_PATH,
101
+ '-N', '',
102
+ '-C', 'awcp-ca',
103
+ ], { stdio: 'inherit' });
104
+ proc.on('close', (code) => {
105
+ if (code === 0)
106
+ resolve();
107
+ else
108
+ reject(new Error(`ssh-keygen failed with code ${code}`));
109
+ });
110
+ proc.on('error', reject);
111
+ });
112
+ }
113
+ /**
114
+ * Configure sshd (requires sudo)
115
+ */
116
+ async function configureSshd() {
117
+ const caKeyPub = `${CA_KEY_PATH}.pub`;
118
+ print('\n Configuring sshd (requires sudo)...');
119
+ // Add TrustedUserCAKeys to sshd_config
120
+ execSync(`echo "TrustedUserCAKeys ${caKeyPub}" | sudo tee -a ${SSHD_CONFIG_PATH}`, {
121
+ stdio: 'inherit',
122
+ });
123
+ // Restart sshd
124
+ if (platform() === 'darwin') {
125
+ execSync('sudo launchctl stop com.openssh.sshd', { stdio: 'inherit' });
126
+ }
127
+ else {
128
+ execSync('sudo systemctl restart sshd || sudo systemctl restart ssh', { stdio: 'inherit' });
129
+ }
130
+ }
131
+ /**
132
+ * Run all checks
133
+ */
134
+ async function runChecks() {
135
+ const results = [];
136
+ // Check ssh-keygen
137
+ const hasSshKeygen = await commandExists('ssh-keygen');
138
+ results.push({
139
+ name: 'ssh-keygen',
140
+ status: hasSshKeygen ? 'ok' : 'missing',
141
+ message: hasSshKeygen ? 'found' : 'not found',
142
+ hint: 'Install OpenSSH client',
143
+ });
144
+ // Check sshfs
145
+ const hasSshfs = await commandExists('sshfs');
146
+ results.push({
147
+ name: 'sshfs',
148
+ status: hasSshfs ? 'ok' : 'missing',
149
+ message: hasSshfs ? 'found' : 'not found',
150
+ hint: platform() === 'darwin'
151
+ ? 'Install: brew install macfuse && brew install sshfs'
152
+ : 'Install: sudo apt install sshfs',
153
+ });
154
+ // Check sshd
155
+ const sshdRunning = await isSshdRunning();
156
+ results.push({
157
+ name: 'sshd',
158
+ status: sshdRunning ? 'ok' : 'missing',
159
+ message: sshdRunning ? 'running' : 'not running',
160
+ hint: platform() === 'darwin'
161
+ ? 'Enable: System Settings → General → Sharing → Remote Login'
162
+ : 'Install & start: sudo apt install openssh-server && sudo systemctl start sshd',
163
+ });
164
+ // Check CA key
165
+ const hasCaKey = await caKeyExists();
166
+ results.push({
167
+ name: 'CA key',
168
+ status: hasCaKey ? 'ok' : 'missing',
169
+ message: hasCaKey ? `exists at ${CA_KEY_PATH}` : 'not found',
170
+ hint: 'Will be auto-generated',
171
+ });
172
+ // Check sshd config (only if CA key exists)
173
+ if (hasCaKey) {
174
+ const sshdConfigured = await isSshdConfigured();
175
+ results.push({
176
+ name: 'sshd TrustedUserCAKeys',
177
+ status: sshdConfigured ? 'ok' : 'missing',
178
+ message: sshdConfigured ? 'configured' : 'not configured',
179
+ hint: `Add to ${SSHD_CONFIG_PATH}: TrustedUserCAKeys ${CA_KEY_PATH}.pub`,
180
+ });
181
+ }
182
+ return results;
183
+ }
184
+ /**
185
+ * Print setup instructions
186
+ */
187
+ function printInstructions(results) {
188
+ const missing = results.filter(r => r.status === 'missing');
189
+ if (missing.length === 0) {
190
+ print('\n \x1b[32m✓ All checks passed! AWCP is ready to use.\x1b[0m\n');
191
+ return;
192
+ }
193
+ print('\n \x1b[33mSetup required:\x1b[0m\n');
194
+ for (const result of missing) {
195
+ if (result.hint) {
196
+ print(` • ${result.name}: ${result.hint}`);
197
+ }
198
+ }
199
+ // Print auto command hint
200
+ const needsSshdConfig = missing.some(r => r.name === 'sshd TrustedUserCAKeys');
201
+ const needsCaKey = missing.some(r => r.name === 'CA key');
202
+ if (needsCaKey || needsSshdConfig) {
203
+ print('\n Or run with --auto to configure automatically:');
204
+ print(' npx @awcp/transport-sshfs setup --auto\n');
205
+ }
206
+ }
207
+ /**
208
+ * Main setup function
209
+ */
210
+ async function setup(options) {
211
+ print('');
212
+ print('╔════════════════════════════════════════════════════════════╗');
213
+ print('║ AWCP SSHFS Transport Setup ║');
214
+ print('╚════════════════════════════════════════════════════════════╝');
215
+ print('');
216
+ print(' Checking dependencies...');
217
+ print('');
218
+ const results = await runChecks();
219
+ for (const result of results) {
220
+ printStatus(result.name, result.status, result.message);
221
+ }
222
+ if (options.check) {
223
+ const allOk = results.every(r => r.status === 'ok');
224
+ process.exit(allOk ? 0 : 1);
225
+ }
226
+ if (options.auto) {
227
+ // Auto-configure
228
+ const needsCaKey = results.some(r => r.name === 'CA key' && r.status === 'missing');
229
+ const needsSshdConfig = results.some(r => r.name === 'sshd TrustedUserCAKeys' && r.status === 'missing');
230
+ if (needsCaKey) {
231
+ print('\n Generating CA key pair...');
232
+ await generateCaKey();
233
+ printStatus('CA key', 'ok', `generated at ${CA_KEY_PATH}`);
234
+ }
235
+ if (needsSshdConfig || needsCaKey) {
236
+ // Re-check if sshd config is needed after CA key generation
237
+ const sshdConfigured = await isSshdConfigured();
238
+ if (!sshdConfigured) {
239
+ await configureSshd();
240
+ printStatus('sshd TrustedUserCAKeys', 'ok', 'configured');
241
+ }
242
+ }
243
+ print('\n \x1b[32m✓ Setup complete! AWCP is ready to use.\x1b[0m\n');
244
+ }
245
+ else {
246
+ printInstructions(results);
247
+ }
248
+ }
249
+ /**
250
+ * Parse CLI arguments and run
251
+ */
252
+ async function main() {
253
+ const args = process.argv.slice(2);
254
+ // Handle help
255
+ if (args.includes('--help') || args.includes('-h')) {
256
+ print(`
257
+ AWCP SSHFS Transport Setup
258
+
259
+ Usage:
260
+ npx @awcp/transport-sshfs setup [options]
261
+
262
+ Options:
263
+ --auto Auto-configure everything (requires sudo for sshd config)
264
+ --check Check only, don't print setup instructions
265
+ --help Show this help message
266
+
267
+ Examples:
268
+ npx @awcp/transport-sshfs setup # Check and show instructions
269
+ npx @awcp/transport-sshfs setup --auto # Auto-configure
270
+ `);
271
+ process.exit(0);
272
+ }
273
+ const options = {
274
+ auto: args.includes('--auto'),
275
+ check: args.includes('--check'),
276
+ };
277
+ try {
278
+ await setup(options);
279
+ }
280
+ catch (error) {
281
+ console.error('\n \x1b[31mError:\x1b[0m', error instanceof Error ? error.message : error);
282
+ process.exit(1);
283
+ }
284
+ }
285
+ main();
286
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
@@ -1,53 +1,20 @@
1
- /**
2
- * SSH Credential Manager configuration
3
- */
4
- export interface CredentialManagerConfig {
5
- /** Directory to store temporary keys (default: ~/.awcp/keys) */
6
- keyDir?: string;
7
- /** SSH server port (default: 22) */
8
- sshPort?: number;
9
- /** SSH server host (default: localhost) */
10
- sshHost?: string;
11
- /** SSH user for connections */
12
- sshUser?: string;
13
- /** Path to authorized_keys file (default: ~/.ssh/authorized_keys) */
14
- authorizedKeysPath?: string;
15
- }
16
- /**
17
- * Generated credential
18
- */
19
- export interface GeneratedCredential {
20
- /** The private key content */
21
- privateKey: string;
22
- /** The public key content */
23
- publicKey: string;
24
- /** Path to the private key file */
25
- privateKeyPath: string;
26
- /** Path to the public key file */
27
- publicKeyPath: string;
28
- /** Delegation ID for tracking */
29
- delegationId: string;
30
- }
1
+ import type { SshCredential } from '@awcp/core';
2
+ import type { CredentialManagerConfig, GeneratedCredential } from '../types.js';
31
3
  /**
32
4
  * SSH Credential Manager
33
5
  *
34
- * Manages temporary SSH keys for AWCP delegations.
35
- *
36
- * TODO [Security]: Consider SSH certificates with built-in expiry for production.
6
+ * Manages temporary SSH certificates for AWCP delegations.
7
+ * Uses SSH certificates with built-in expiry for automatic TTL enforcement.
37
8
  */
38
9
  export declare class CredentialManager {
39
10
  private config;
40
11
  private activeCredentials;
41
- constructor(config?: CredentialManagerConfig);
12
+ constructor(config: CredentialManagerConfig);
42
13
  /**
43
- * Get the path to authorized_keys file
14
+ * Generate a temporary SSH key pair and sign certificate with TTL
44
15
  */
45
- private getAuthorizedKeysPath;
46
- /**
47
- * Generate a temporary SSH key pair for a delegation
48
- */
49
- generateCredential(delegationId: string, _ttlSeconds: number): Promise<{
50
- credential: string;
16
+ generateCredential(delegationId: string, ttlSeconds: number): Promise<{
17
+ credential: SshCredential;
51
18
  endpoint: {
52
19
  host: string;
53
20
  port: number;
@@ -55,7 +22,11 @@ export declare class CredentialManager {
55
22
  };
56
23
  }>;
57
24
  /**
58
- * Revoke a credential
25
+ * Ensure CA key exists, auto-generate if not present
26
+ */
27
+ private ensureCaKey;
28
+ /**
29
+ * Revoke a credential (delete key files, certificate expires automatically)
59
30
  */
60
31
  revokeCredential(delegationId: string): Promise<void>;
61
32
  /**
@@ -66,22 +37,14 @@ export declare class CredentialManager {
66
37
  * Revoke all credentials
67
38
  */
68
39
  revokeAll(): Promise<void>;
69
- /**
70
- * Clean up stale AWCP keys from authorized_keys (call on startup)
71
- */
72
- cleanupStaleKeys(): Promise<number>;
73
40
  /**
74
41
  * Clean up stale key files from key directory (call on startup)
75
42
  */
76
43
  cleanupStaleKeyFiles(): Promise<number>;
77
44
  /**
78
- * Add a public key to authorized_keys
79
- */
80
- private addToAuthorizedKeys;
81
- /**
82
- * Remove a public key from authorized_keys by delegation ID
45
+ * Sign public key with CA to create certificate with TTL
83
46
  */
84
- private removeFromAuthorizedKeys;
47
+ private signCertificate;
85
48
  /**
86
49
  * Execute ssh-keygen to generate a key pair
87
50
  */
@@ -1 +1 @@
1
- {"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/delegator/credential-manager.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;CACtB;AASD;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,iBAAiB,CAA0C;gBAEvD,MAAM,CAAC,EAAE,uBAAuB;IAI5C;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;OAEG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;IAsCF;;OAEG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB3D;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIpE;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAMhC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BzC;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAkC7C;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;YACW,wBAAwB;IAkBtC;;OAEG;IACH,OAAO,CAAC,aAAa;CAyBtB"}
1
+ {"version":3,"file":"credential-manager.d.ts","sourceRoot":"","sources":["../../src/delegator/credential-manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAIhF;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,iBAAiB,CAA0C;gBAEvD,MAAM,EAAE,uBAAuB;IAI3C;;OAEG;IACG,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QACT,UAAU,EAAE,aAAa,CAAC;QAC1B,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;IA4CF;;OAEG;YACW,WAAW;IA0BzB;;OAEG;IACG,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIpE;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAMhC;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IA8B7C;;OAEG;IACH,OAAO,CAAC,eAAe;IAgCvB;;OAEG;IACH,OAAO,CAAC,aAAa;CAyBtB"}