--- lbbs/src/test_ssh_server.c 2025/06/04 13:42:53 1.3 +++ lbbs/src/test_ssh_server.c 2025/11/04 14:58:56 1.13 @@ -1,19 +1,29 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * test_ssh_server + * - tester for network server with SSH support + * + * Copyright (C) 2004-2025 Leaflet + */ + +// This test was written based on libssh example/proxy.c + #include "log.h" #include +#include #include #include -#include #ifndef BUF_SIZE #define BUF_SIZE 2048 #endif -#define SSH_HOST_KEYFILE "../conf/ssh_host_rsa_key" +#define SSH_HOST_RSA_KEYFILE "../conf/ssh_host_rsa_key" #define USER "test" #define PASSWORD "123456" -static ssh_channel channel; +static ssh_channel SSH_channel; static int authenticated = 0; static int tries = 0; static int error = 0; @@ -64,42 +74,45 @@ static int shell_request(ssh_session ses log_common("Allocated shell\n"); return 0; } + struct ssh_channel_callbacks_struct channel_cb = { .channel_pty_request_function = pty_request, .channel_shell_request_function = shell_request}; -static ssh_channel new_session_channel(ssh_session session, void *userdata) +static ssh_channel channel_open(ssh_session session, void *userdata) { (void)session; (void)userdata; - if (channel != NULL) + if (SSH_channel != NULL) return NULL; log_common("Allocated session channel\n"); - channel = ssh_channel_new(session); + SSH_channel = ssh_channel_new(session); ssh_callbacks_init(&channel_cb); - ssh_set_channel_callbacks(channel, &channel_cb); + ssh_set_channel_callbacks(SSH_channel, &channel_cb); - return channel; + return SSH_channel; } int ssh_server(const char *hostaddr, unsigned int port) { - ssh_session session; ssh_bind sshbind; + ssh_session session; ssh_event event; struct ssh_server_callbacks_struct cb = { .userdata = NULL, .auth_password_function = auth_password, - .channel_open_request_session_function = new_session_channel}; + .channel_open_request_session_function = channel_open}; + + long int ssh_timeout = 0; char buf[BUF_SIZE]; char host[128] = ""; int i, r; - int ssh_log_level = SSH_LOG_WARNING; + int ssh_log_level = SSH_LOG_PROTOCOL; ssh_init(); @@ -107,7 +120,14 @@ int ssh_server(const char *hostaddr, uns if (ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, hostaddr) < 0 || ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT, &port) < 0 || - ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, SSH_HOST_KEYFILE) < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, SSH_HOST_RSA_KEYFILE) < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY_ALGORITHMS, "ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_PUBKEY_ACCEPTED_KEY_TYPES, "ssh-rsa,rsa-sha2-512,rsa-sha2-256,ecdsa-sha2-nistp256") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_KEY_EXCHANGE, "curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HMAC_C_S, "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HMAC_S_C, "umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_CIPHERS_C_S, "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com") < 0 || + ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_CIPHERS_S_C, "chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com") < 0 || ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY, &ssh_log_level) < 0) { log_error("Error setting SSH bind options: %s\n", ssh_get_error(sshbind)); @@ -137,17 +157,26 @@ int ssh_server(const char *hostaddr, uns ssh_callbacks_init(&cb); ssh_set_server_callbacks(session, &cb); + ssh_timeout = 60; // second + if (ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) + { + log_error("Error setting SSH options: %s\n", ssh_get_error(session)); + ssh_disconnect(session); + _exit(1); + } + if (ssh_handle_key_exchange(session)) { log_error("ssh_handle_key_exchange: %s\n", ssh_get_error(session)); - return 1; + ssh_disconnect(session); + _exit(1); } ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD | SSH_AUTH_METHOD_GSSAPI_MIC); event = ssh_event_new(); ssh_event_add_session(event, session); - while (!(authenticated && channel != NULL)) + while (!(authenticated && SSH_channel != NULL)) { if (error) break; @@ -170,14 +199,22 @@ int ssh_server(const char *hostaddr, uns log_common("Authenticated and got a channel\n"); } + ssh_timeout = 0; + if (ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &ssh_timeout) < 0) + { + log_error("Error setting SSH options: %s\n", ssh_get_error(session)); + ssh_disconnect(session); + _exit(1); + } + snprintf(buf, sizeof(buf), "Hello, welcome to the Sample SSH proxy.\r\nPlease select your destination: "); - ssh_channel_write(channel, buf, (uint32_t)strlen(buf)); + ssh_channel_write(SSH_channel, buf, (uint32_t)strlen(buf)); do { - i = ssh_channel_read(channel, buf, sizeof(buf), 0); + i = ssh_channel_read(SSH_channel, buf, sizeof(buf), 0); if (i > 0) { - ssh_channel_write(channel, buf, (uint32_t)i); + ssh_channel_write(SSH_channel, buf, (uint32_t)i); if (strlen(host) + (size_t)i < sizeof(host)) { strncat(host, buf, (size_t)i); @@ -185,7 +222,7 @@ int ssh_server(const char *hostaddr, uns if (strchr(host, '\x0d')) { *strchr(host, '\x0d') = '\0'; - ssh_channel_write(channel, "\n", 1); + ssh_channel_write(SSH_channel, "\n", 1); break; } } @@ -196,7 +233,7 @@ int ssh_server(const char *hostaddr, uns } } while (i > 0); snprintf(buf, sizeof(buf), "Trying to connect to \"%s\"\r\n", host); - ssh_channel_write(channel, buf, (uint32_t)strlen(buf)); + ssh_channel_write(SSH_channel, buf, (uint32_t)strlen(buf)); log_common("%s", buf); ssh_disconnect(session);