* Start a minimal SSH server that only accepts publickey auth for USERNAME * using the provided public-key string. * * Returns { port, close }.
(allowedPublicKey, { debug = false } = {})
| 124 | * Returns { port, close }. |
| 125 | */ |
| 126 | async function startServer (allowedPublicKey, { debug = false } = {}) { |
| 127 | const clients = new Set() |
| 128 | const server = new Server({ hostKeys: [HOST_KEY.private] }, (client) => { |
| 129 | clients.add(client) |
| 130 | client.on('close', () => clients.delete(client)) |
| 131 | client.on('end', () => clients.delete(client)) |
| 132 | |
| 133 | client.on('authentication', (ctx) => { |
| 134 | if (debug) { |
| 135 | console.log('[server] auth method:', ctx.method, 'user:', ctx.username) |
| 136 | } |
| 137 | if (ctx.method === 'none') { |
| 138 | return ctx.reject(['publickey']) |
| 139 | } |
| 140 | if ( |
| 141 | ctx.method === 'publickey' && |
| 142 | ctx.username === USERNAME && |
| 143 | publicKeyMatchesCtx(ctx, allowedPublicKey) |
| 144 | ) { |
| 145 | if (debug) console.log('[server] accepted publickey auth') |
| 146 | return ctx.accept() |
| 147 | } |
| 148 | // reject but keep publickey in the advertised list so the client can |
| 149 | // try the ssh agent after failing with a file key |
| 150 | return ctx.reject(['publickey']) |
| 151 | }) |
| 152 | |
| 153 | client.on('ready', () => { |
| 154 | client.on('session', (accept) => { |
| 155 | const sess = accept() |
| 156 | sess.on('env', (accept) => accept()) |
| 157 | sess.on('pty', (accept) => accept()) |
| 158 | sess.on('shell', (accept) => { |
| 159 | const stream = accept() |
| 160 | stream.write('electerm-agent-test ready\n') |
| 161 | }) |
| 162 | }) |
| 163 | }) |
| 164 | }) |
| 165 | |
| 166 | server.listen(0, '127.0.0.1') |
| 167 | await once(server, 'listening') |
| 168 | const { port } = server.address() |
| 169 | if (debug) console.log('[server] listening on port', port) |
| 170 | |
| 171 | return { |
| 172 | port, |
| 173 | async close () { |
| 174 | for (const c of clients) c.end() |
| 175 | await new Promise((resolve, reject) => { |
| 176 | server.close((err) => (err ? reject(err) : resolve())) |
| 177 | }) |
| 178 | } |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | /** |
| 183 | * Minimal ws mock that automatically trusts unknown host keys. |
no test coverage detected