chore: template keyboard-interactive
This commit is contained in:
parent
2bd225e12e
commit
0899cb0efa
3 changed files with 164 additions and 6 deletions
85
app/ssh.js
85
app/ssh.js
|
@ -8,12 +8,24 @@ const { maskSensitiveData } = require("./utils")
|
|||
|
||||
const debug = createNamespacedDebug("ssh")
|
||||
|
||||
/**
|
||||
* SSHConnection class handles SSH connections and operations.
|
||||
* @class
|
||||
* @param {Object} config - Configuration object for the SSH connection.
|
||||
*/
|
||||
function SSHConnection(config) {
|
||||
this.config = config
|
||||
this.conn = null
|
||||
this.stream = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to the SSH server using the provided credentials.
|
||||
* @function
|
||||
* @memberof SSHConnection
|
||||
* @param {Object} creds - The credentials object containing host, port, username, and password.
|
||||
* @returns {Promise<SSH>} - A promise that resolves with the SSH connection instance.
|
||||
*/
|
||||
SSHConnection.prototype.connect = function(creds) {
|
||||
debug("connect: %O", maskSensitiveData(creds))
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -38,14 +50,66 @@ SSHConnection.prototype.connect = function(creds) {
|
|||
reject(error)
|
||||
})
|
||||
|
||||
this.conn.on(
|
||||
"keyboard-interactive",
|
||||
(name, instructions, lang, prompts, finish) => {
|
||||
this.handleKeyboardInteractive(
|
||||
creds,
|
||||
name,
|
||||
instructions,
|
||||
lang,
|
||||
prompts,
|
||||
finish
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
this.conn.connect(sshConfig)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the SSH configuration
|
||||
* @param {Object} creds - The credentials object
|
||||
* @returns {Object} The SSH configuration object
|
||||
* Handles keyboard-interactive authentication prompts.
|
||||
* @function
|
||||
* @memberof SSHConnection
|
||||
* @param {Object} creds - The credentials object containing password.
|
||||
* @param {string} name - The name of the authentication request.
|
||||
* @param {string} instructions - The instructions for the keyboard-interactive prompt.
|
||||
* @param {string} lang - The language of the prompt.
|
||||
* @param {Array<Object>} prompts - The list of prompts provided by the server.
|
||||
* @param {Function} finish - The callback to complete the keyboard-interactive authentication.
|
||||
*/
|
||||
SSHConnection.prototype.handleKeyboardInteractive = function(
|
||||
creds,
|
||||
name,
|
||||
instructions,
|
||||
lang,
|
||||
prompts,
|
||||
finish
|
||||
) {
|
||||
debug("handleKeyboardInteractive: Keyboard-interactive auth %O", prompts)
|
||||
const responses = []
|
||||
|
||||
for (let i = 0; i < prompts.length; i += 1) {
|
||||
if (prompts[i].prompt.toLowerCase().includes("password")) {
|
||||
responses.push(creds.password)
|
||||
} else {
|
||||
// todo: For any non-password prompts, we meed to implement a way to
|
||||
// get responses from the user through a modal. For now, we'll just
|
||||
// send an empty string
|
||||
responses.push("")
|
||||
}
|
||||
}
|
||||
|
||||
finish(responses)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the SSH configuration object based on credentials.
|
||||
* @function
|
||||
* @memberof SSHConnection
|
||||
* @param {Object} creds - The credentials object containing host, port, username, and password.
|
||||
* @returns {Object} - The SSH configuration object.
|
||||
*/
|
||||
SSHConnection.prototype.getSSHConfig = function(creds) {
|
||||
return {
|
||||
|
@ -62,6 +126,13 @@ SSHConnection.prototype.getSSHConfig = function(creds) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an interactive shell session over the SSH connection.
|
||||
* @function
|
||||
* @memberof SSHConnection
|
||||
* @param {Object} [options] - Optional parameters for the shell.
|
||||
* @returns {Promise<Object>} - A promise that resolves with the SSH shell stream.
|
||||
*/
|
||||
SSHConnection.prototype.shell = function(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.conn.shell(options, (err, stream) => {
|
||||
|
@ -76,9 +147,11 @@ SSHConnection.prototype.shell = function(options) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Resizes the terminal
|
||||
* @param {number} rows - The number of rows
|
||||
* @param {number} cols - The number of columns
|
||||
* Resizes the terminal window for the current SSH session.
|
||||
* @function
|
||||
* @memberof SSHConnection
|
||||
* @param {number} rows - The number of rows for the terminal.
|
||||
* @param {number} cols - The number of columns for the terminal.
|
||||
*/
|
||||
SSHConnection.prototype.resizeTerminal = function(rows, cols) {
|
||||
if (this.stream) {
|
||||
|
|
27
tests/servers/keyboard-interactive/Dockerfile
Normal file
27
tests/servers/keyboard-interactive/Dockerfile
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Use the Debian Bullseye Slim image as the base
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# Install the necessary packages
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
openssh-server && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Configure SSH server
|
||||
RUN mkdir /var/run/sshd && \
|
||||
sed -i 's/^ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config && \
|
||||
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config && \
|
||||
echo 'Port 4444' >> /etc/ssh/sshd_config && \
|
||||
echo 'UsePAM yes' >> /etc/ssh/sshd_config && \
|
||||
echo 'AuthenticationMethods keyboard-interactive' >> /etc/ssh/sshd_config
|
||||
|
||||
# Add a test user with a password
|
||||
RUN useradd -m testuser && \
|
||||
echo "testuser:testpassword" | chpasswd
|
||||
|
||||
# Expose port 4444
|
||||
EXPOSE 4444
|
||||
|
||||
# Start the SSH server
|
||||
CMD ["/usr/sbin/sshd", "-D", "-e", "-d", "-d", "-d"]
|
58
tests/servers/keyboard-interactive/README.md
Normal file
58
tests/servers/keyboard-interactive/README.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
# Keyboard Interactive SSH Server
|
||||
A test SSH server that uses keyboard-interactive authentication and listens on port 4444:
|
||||
|
||||
```Dockerfile
|
||||
# Use the Debian Bullseye Slim image as the base
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# Install the necessary packages
|
||||
# Use the Debian Bullseye Slim image as the base
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
# Install the necessary packages
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
openssh-server && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Configure SSH server
|
||||
RUN mkdir /var/run/sshd && \
|
||||
sed -i 's/^ChallengeResponseAuthentication no/ChallengeResponseAuthentication yes/' /etc/ssh/sshd_config && \
|
||||
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config && \
|
||||
echo 'Port 4444' >> /etc/ssh/sshd_config && \
|
||||
echo 'UsePAM yes' >> /etc/ssh/sshd_config && \
|
||||
echo 'AuthenticationMethods keyboard-interactive' >> /etc/ssh/sshd_config
|
||||
|
||||
# Add a test user with a password
|
||||
RUN useradd -m testuser && \
|
||||
echo "testuser:testpassword" | chpasswd
|
||||
|
||||
# Expose port 4444
|
||||
EXPOSE 4444
|
||||
|
||||
# Start the SSH server
|
||||
CMD ["/usr/sbin/sshd", "-D", "-e", "-d -d -d"]
|
||||
```
|
||||
|
||||
### Instructions:
|
||||
|
||||
1. **Build the Docker image**:
|
||||
```bash
|
||||
docker build -t keyboard-ssh-server .
|
||||
```
|
||||
|
||||
2. **Run the container**:
|
||||
```bash
|
||||
docker run --rm -p 4444:4444 --name keyboard-ssh-server keyboard-ssh-server
|
||||
```
|
||||
|
||||
This Dockerfile sets up an SSH server that listens on port 4444 and uses keyboard-interactive authentication. The `testuser` has been created with the password `testpassword`.
|
||||
|
||||
You can connect to this SSH server using the following command:
|
||||
|
||||
```bash
|
||||
ssh -p 4444 testuser@localhost
|
||||
```
|
||||
|
||||
You'll be prompted for a password as part of the keyboard-interactive authentication process.
|
Loading…
Reference in a new issue