Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The `noxssh` executable is produced in `bin/` (or `build/bin/` depending on your
### Usage

```text
Usage: noxssh [-h] [-d|-dd|-ddd] [-p port] [-w password] [user@]host [command]
Usage: noxssh [-h] [-d|-dd|-ddd] [-T] [-p port] [-w password] [user@]host [command]
```

| Example | Description |
Expand All @@ -59,8 +59,9 @@ Usage: noxssh [-h] [-d|-dd|-ddd] [-p port] [-w password] [user@]host [command]
| `noxssh user@example.com "uname -a"` | Run a single command and exit |
| `noxssh -d user@example.com` | Basic debug logging |
| `noxssh -ddd user@example.com` | Packet-level debug logging |
| `noxssh -T user@example.com` | Request shell without PTY allocation |

If `user@` is omitted, the default username is `user`. You are prompted for the password when using password authentication unless `-w` is provided.
If `user@` is omitted, the default username is `user`. You are prompted for the password when using password authentication unless `-w` is provided. Use `-T` to disable PTY allocation (like OpenSSH), which is useful for non-interactive/automation scenarios.

---

Expand Down
13 changes: 11 additions & 2 deletions client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ typedef int app_socket_t;
#endif

#include "version.h"
#include "../noxtls/noxtls_version.h"
#include "noxssh_common.h"

/** @brief Default username when user@host is not provided. */
Expand Down Expand Up @@ -80,12 +81,14 @@ typedef struct
static void noxssh_print_usage(const char * prog)
{
printf("%s " NOXSSH_VERSION_STRING "\n", (prog != NULL ? prog : "noxssh"));
printf("Usage: %s [-h] [-d|-dd|-ddd] [-p port] [-w password] [user@]host [command]\n", (prog != NULL ? prog : "noxssh"));
printf("Using NoxTLS Library %s\n", NOXTLS_VERSION_STRING);
printf("Usage: %s [-h] [-d|-dd|-ddd] [-T] [-p port] [-w password] [user@]host [command]\n", (prog != NULL ? prog : "noxssh"));
printf("Options:\n");
printf(" -h, --help Show this help and exit.\n");
printf(" -d Enable basic SSH debug output.\n");
printf(" -dd Enable verbose SSH debug output.\n");
printf(" -ddd Enable packet-level SSH debug output.\n");
printf(" -T Disable PTY allocation for shell sessions.\n");
printf(" -p port SSH server port (default: 22).\n");
printf(" -w password Password (avoid on command line in production).\n");
printf("Examples:\n");
Expand Down Expand Up @@ -514,6 +517,7 @@ int main(int argc, char ** argv)
char password[NOXSSH_MAX_PASSWORD_LEN + 1u];
int password_set = 0;
int command_set = 0;
int request_pty = 1;
int debug_level = 0;
int i = 0;
noxssh_conn_t conn;
Expand Down Expand Up @@ -589,6 +593,11 @@ int main(int argc, char ** argv)
continue;
}

if(strcmp(argv[i], "-T") == 0) {
request_pty = 0;
continue;
}

if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
noxssh_print_usage(argv[0]);
#ifdef _WIN32
Expand Down Expand Up @@ -778,7 +787,7 @@ int main(int argc, char ** argv)
}
noxssh_print_channel_output(&client);
} else {
rc = netnox_ssh_client_request_shell(&client);
rc = netnox_ssh_client_request_shell_ex(&client, (uint8_t)request_pty);
if(rc != NETNOX_RETURN_SUCCESS) {
printf("ERROR: Failed to request remote shell.\n");
(void)netnox_ssh_client_close(&client);
Expand Down
4 changes: 2 additions & 2 deletions client/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
/** @brief Minor version number. */
#define NOXSSH_VERSION_MINOR 1
/** @brief Patch version number. */
#define NOXSSH_VERSION_PATCH 2
#define NOXSSH_VERSION_PATCH 10

/** @brief Version string for display (e.g. "0.1.0"). */
#define NOXSSH_VERSION_STRING "0.1.2"
#define NOXSSH_VERSION_STRING "0.1.10"

#endif /* NOXSSH_VERSION_H */
122 changes: 66 additions & 56 deletions common/noxssh_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2153,7 +2153,8 @@ netnox_return_t netnox_ssh_client_exec(netnox_ssh_client_t * client, const char
return NETNOX_RETURN_SUCCESS;
}

netnox_return_t netnox_ssh_client_request_shell(netnox_ssh_client_t * client)
netnox_return_t netnox_ssh_client_request_shell_ex(netnox_ssh_client_t * client,
uint8_t request_pty)
{
uint8_t payload[512];
uint32_t payload_len = 0u;
Expand All @@ -2171,62 +2172,66 @@ netnox_return_t netnox_ssh_client_request_shell(netnox_ssh_client_t * client)
return NETNOX_RETURN_BAD_PARAM;
}

/* Ask server for a PTY so shell behaves interactively (prompts/line editing). */
payload_len = 0u;
if(netnox_ssh_payload_append_u8(payload, &payload_len, (uint32_t)sizeof(payload), NETNOX_SSH_MSG_CHANNEL_REQUEST) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), client->remote_channel_id) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload),
(const uint8_t *)"pty-req",
(uint32_t)strlen("pty-req")) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u8(payload, &payload_len, (uint32_t)sizeof(payload), 1u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload),
(const uint8_t *)"xterm-256color",
(uint32_t)strlen("xterm-256color")) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 80u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 24u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload), NULL, 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_send_packet(client, payload, payload_len) != NETNOX_RETURN_SUCCESS) {
SSH_DEBUG("request_shell: send CHANNEL_REQUEST(pty-req) failed");
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_wait_for_message(client,
NETNOX_SSH_MSG_CHANNEL_SUCCESS,
NETNOX_SSH_MSG_CHANNEL_FAILURE,
rsp,
(uint32_t)sizeof(rsp),
&rsp_len) != NETNOX_RETURN_SUCCESS) {
SSH_DEBUG("request_shell: wait_for_message pty-req success/failure failed");
return NETNOX_RETURN_FAILED;
}
if(rsp_len == 0u || rsp[0] != NETNOX_SSH_MSG_CHANNEL_SUCCESS) {
SSH_DEBUG("request_shell: pty-req rejected (rsp_len=%u type=%u)",
(unsigned)rsp_len,
(unsigned)(rsp_len > 0u ? rsp[0] : 0xFFu));
return NETNOX_RETURN_FAILED;
if(request_pty != 0u) {
/* Ask server for a PTY so shell behaves interactively (prompts/line editing). */
payload_len = 0u;
if(netnox_ssh_payload_append_u8(payload, &payload_len, (uint32_t)sizeof(payload), NETNOX_SSH_MSG_CHANNEL_REQUEST) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), client->remote_channel_id) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload),
(const uint8_t *)"pty-req",
(uint32_t)strlen("pty-req")) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u8(payload, &payload_len, (uint32_t)sizeof(payload), 1u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload),
(const uint8_t *)"xterm-256color",
(uint32_t)strlen("xterm-256color")) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 80u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 24u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_u32(payload, &payload_len, (uint32_t)sizeof(payload), 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_payload_append_string(payload, &payload_len, (uint32_t)sizeof(payload), NULL, 0u) != NETNOX_RETURN_SUCCESS) {
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_send_packet(client, payload, payload_len) != NETNOX_RETURN_SUCCESS) {
SSH_DEBUG("request_shell: send CHANNEL_REQUEST(pty-req) failed");
return NETNOX_RETURN_FAILED;
}
if(netnox_ssh_wait_for_message(client,
NETNOX_SSH_MSG_CHANNEL_SUCCESS,
NETNOX_SSH_MSG_CHANNEL_FAILURE,
rsp,
(uint32_t)sizeof(rsp),
&rsp_len) != NETNOX_RETURN_SUCCESS) {
SSH_DEBUG("request_shell: wait_for_message pty-req success/failure failed");
return NETNOX_RETURN_FAILED;
}
if(rsp_len == 0u || rsp[0] != NETNOX_SSH_MSG_CHANNEL_SUCCESS) {
SSH_DEBUG("request_shell: pty-req rejected (rsp_len=%u type=%u)",
(unsigned)rsp_len,
(unsigned)(rsp_len > 0u ? rsp[0] : 0xFFu));
return NETNOX_RETURN_FAILED;
}
SSH_DEBUG("request_shell: CHANNEL_REQUEST(pty-req) accepted");
} else {
SSH_DEBUG("request_shell: PTY request disabled by caller");
}
SSH_DEBUG("request_shell: CHANNEL_REQUEST(pty-req) accepted");

payload_len = 0u;
if(netnox_ssh_payload_append_u8(payload, &payload_len, (uint32_t)sizeof(payload), NETNOX_SSH_MSG_CHANNEL_REQUEST) != NETNOX_RETURN_SUCCESS) {
Expand Down Expand Up @@ -2268,6 +2273,11 @@ netnox_return_t netnox_ssh_client_request_shell(netnox_ssh_client_t * client)
return NETNOX_RETURN_SUCCESS;
}

netnox_return_t netnox_ssh_client_request_shell(netnox_ssh_client_t * client)
{
return netnox_ssh_client_request_shell_ex(client, 1u);
}

netnox_return_t netnox_ssh_client_send_data(netnox_ssh_client_t * client,
const uint8_t * data,
uint32_t len)
Expand Down
2 changes: 2 additions & 0 deletions common/noxssh_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ extern netnox_return_t netnox_ssh_client_authenticate(netnox_ssh_client_t * clie
extern netnox_return_t netnox_ssh_client_open_session(netnox_ssh_client_t * client);
extern netnox_return_t netnox_ssh_client_exec(netnox_ssh_client_t * client,
const char * command);
extern netnox_return_t netnox_ssh_client_request_shell_ex(netnox_ssh_client_t * client,
uint8_t request_pty);
extern netnox_return_t netnox_ssh_client_request_shell(netnox_ssh_client_t * client);
extern netnox_return_t netnox_ssh_client_send_data(netnox_ssh_client_t * client,
const uint8_t * data,
Expand Down
2 changes: 1 addition & 1 deletion noxtls
Submodule noxtls updated 262 files
Loading