Compare commits

..

11 Commits

Author SHA1 Message Date
Jakub Jelen
00f1d6fac2 Add RequiredRsaSize configuration option
to both client and server configuration file

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:06:43 +02:00
Jakub Jelen
029754efb3 examples: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:59 +02:00
Jakub Jelen
a49e0c2a84 examples: Replace magic numbers with FD constants
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:58 +02:00
Jakub Jelen
8966e577ab connector: Improve logging
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:57 +02:00
Jakub Jelen
dc45b8f3f1 channels: Improve logging information about channels
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:56 +02:00
Jakub Jelen
c932790b82 connector: Fix default connector flags
Originally reported by Jeremy Cross <jcross@beyondtrust.com> in #461

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:55 +02:00
Jakub Jelen
8a0aa17bca connector: Reformat
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:55 +02:00
Jakub Jelen
ecb11f1a18 tests: Fix wording in comment to make sense
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:04:54 +02:00
Jakub Jelen
6aea779918 sftpserver: Fix loop termination
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:03:46 +02:00
Jakub Jelen
a51384fe4e sftpserver: Remove some needless parts
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:03:45 +02:00
Jakub Jelen
c55140272f examples: Add more flexibility to set verbosity
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
2025-10-01 16:03:44 +02:00
12 changed files with 119 additions and 83 deletions

View File

@@ -148,6 +148,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
ssh_bind sshbind = state->input; ssh_bind sshbind = state->input;
static int no_default_keys = 0; static int no_default_keys = 0;
static int rsa_already_set = 0, ecdsa_already_set = 0; static int rsa_already_set = 0, ecdsa_already_set = 0;
static int verbosity = 0;
switch (key) switch (key)
{ {
@@ -176,8 +177,10 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1); strncpy(authorizedkeys, arg, DEF_STR_SIZE - 1);
break; break;
case 'v': case 'v':
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, verbosity++;
"3"); ssh_bind_options_set(sshbind,
SSH_BIND_OPTIONS_LOG_VERBOSITY,
&verbosity);
break; break;
case ARGP_KEY_ARG: case ARGP_KEY_ARG:
if (state->arg_num >= 1) if (state->arg_num >= 1)
@@ -213,10 +216,7 @@ static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
#endif /* HAVE_ARGP_H */ #endif /* HAVE_ARGP_H */
/* A userdata struct for channel. */ /* A userdata struct for channel. */
struct channel_data_struct struct channel_data_struct {
{
/* Event which is used to poll the above descriptors. */
ssh_event event;
sftp_session sftp; sftp_session sftp;
}; };
@@ -378,18 +378,11 @@ static void handle_session(ssh_event event, ssh_session session)
do { do {
/* Poll the main event which takes care of the session, the channel and /* Poll the main event which takes care of the session, the channel and
* even our child process's stdout/stderr (once it's started). */ * even our child process's stdout/stderr (once it's started). */
if (ssh_event_dopoll(event, -1) == SSH_ERROR) { if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
ssh_channel_close(sdata.channel); ssh_channel_close(sdata.channel);
} }
} while (ssh_channel_is_open(sdata.channel) &&
/* If child process's stdout/stderr has been registered with the event, !ssh_channel_is_eof(sdata.channel));
* or the child process hasn't started yet, continue. */
if (cdata.event != NULL) {
continue;
}
/* FIXME The server keeps hanging in the poll above when the client
* closes the channel */
} while (ssh_channel_is_open(sdata.channel));
ssh_channel_send_eof(sdata.channel); ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel); ssh_channel_close(sdata.channel);

View File

@@ -39,8 +39,6 @@
#include <libssh/callbacks.h> #include <libssh/callbacks.h>
#include <libssh/libssh.h> #include <libssh/libssh.h>
#include <libssh/sftp.h>
#include "examples_common.h" #include "examples_common.h"
#define MAXCMD 10 #define MAXCMD 10
@@ -112,8 +110,8 @@ static int opts(int argc, char **argv)
{ {
int i; int i;
while((i = getopt(argc,argv,"T:P:F:")) != -1) { while ((i = getopt(argc, argv, "T:P:F:")) != -1) {
switch(i){ switch (i) {
case 'P': case 'P':
pcap_file = optarg; pcap_file = optarg;
break; break;
@@ -159,16 +157,14 @@ static void cfmakeraw(struct termios *termios_p)
static void do_cleanup(int i) static void do_cleanup(int i)
{ {
/* unused variable */ (void)i;
(void) i;
tcsetattr(0, TCSANOW, &terminal); tcsetattr(0, TCSANOW, &terminal);
} }
static void do_exit(int i) static void do_exit(int i)
{ {
/* unused variable */ (void)i;
(void) i;
do_cleanup(0); do_cleanup(0);
exit(0); exit(0);
@@ -179,7 +175,7 @@ static int signal_delayed = 0;
#ifdef SIGWINCH #ifdef SIGWINCH
static void sigwindowchanged(int i) static void sigwindowchanged(int i)
{ {
(void) i; (void)i;
signal_delayed = 1; signal_delayed = 1;
} }
#endif #endif
@@ -213,18 +209,18 @@ static void select_loop(ssh_session session,ssh_channel channel)
/* stdin */ /* stdin */
connector_in = ssh_connector_new(session); connector_in = ssh_connector_new(session);
ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT); ssh_connector_set_out_channel(connector_in, channel, SSH_CONNECTOR_STDINOUT);
ssh_connector_set_in_fd(connector_in, 0); ssh_connector_set_in_fd(connector_in, STDIN_FILENO);
ssh_event_add_connector(event, connector_in); ssh_event_add_connector(event, connector_in);
/* stdout */ /* stdout */
connector_out = ssh_connector_new(session); connector_out = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_out, 1); ssh_connector_set_out_fd(connector_out, STDOUT_FILENO);
ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT); ssh_connector_set_in_channel(connector_out, channel, SSH_CONNECTOR_STDINOUT);
ssh_event_add_connector(event, connector_out); ssh_event_add_connector(event, connector_out);
/* stderr */ /* stderr */
connector_err = ssh_connector_new(session); connector_err = ssh_connector_new(session);
ssh_connector_set_out_fd(connector_err, 2); ssh_connector_set_out_fd(connector_err, STDERR_FILENO);
ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR); ssh_connector_set_in_channel(connector_err, channel, SSH_CONNECTOR_STDERR);
ssh_event_add_connector(event, connector_err); ssh_event_add_connector(event, connector_err);
@@ -253,7 +249,7 @@ static void shell(ssh_session session)
{ {
ssh_channel channel = NULL; ssh_channel channel = NULL;
struct termios terminal_local; struct termios terminal_local;
int interactive=isatty(0); int interactive = isatty(0);
channel = ssh_channel_new(session); channel = ssh_channel_new(session);
if (channel == NULL) { if (channel == NULL) {

View File

@@ -52,6 +52,7 @@ enum ssh_bind_config_opcode_e {
BIND_CFG_MATCH, BIND_CFG_MATCH,
BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES, BIND_CFG_PUBKEY_ACCEPTED_KEY_TYPES,
BIND_CFG_HOSTKEY_ALGORITHMS, BIND_CFG_HOSTKEY_ALGORITHMS,
BIND_CFG_REQUIRED_RSA_SIZE,
BIND_CFG_MAX /* Keep this one last in the list */ BIND_CFG_MAX /* Keep this one last in the list */
}; };

View File

@@ -66,6 +66,7 @@ enum ssh_config_opcode_e {
SOC_CONTROLMASTER, SOC_CONTROLMASTER,
SOC_CONTROLPATH, SOC_CONTROLPATH,
SOC_CERTIFICATE, SOC_CERTIFICATE,
SOC_REQUIRED_RSA_SIZE,
SOC_MAX /* Keep this one last in the list */ SOC_MAX /* Keep this one last in the list */
}; };

View File

@@ -104,6 +104,11 @@ ssh_bind_config_keyword_table[] = {
.opcode = BIND_CFG_HOSTKEY_ALGORITHMS, .opcode = BIND_CFG_HOSTKEY_ALGORITHMS,
.allowed_in_match = true .allowed_in_match = true
}, },
{
.name = "requiredrsasize",
.opcode = BIND_CFG_REQUIRED_RSA_SIZE,
.allowed_in_match = true
},
{ {
.opcode = BIND_CFG_UNKNOWN, .opcode = BIND_CFG_UNKNOWN,
} }
@@ -293,6 +298,7 @@ ssh_bind_config_parse_line(ssh_bind bind,
const char *p = NULL; const char *p = NULL;
char *s = NULL, *x = NULL; char *s = NULL, *x = NULL;
char *keyword = NULL; char *keyword = NULL;
long l;
size_t len; size_t len;
int rc = 0; int rc = 0;
@@ -594,6 +600,18 @@ ssh_bind_config_parse_line(ssh_bind bind,
} }
} }
break; break;
case BIND_CFG_REQUIRED_RSA_SIZE:
l = ssh_config_get_long(&s, -1);
if (l >= 0 && (*parser_flags & PARSING)) {
rc = ssh_bind_options_set(bind, SSH_BIND_OPTIONS_RSA_MIN_SIZE, &l);
if (rc != 0) {
SSH_LOG(SSH_LOG_TRACE,
"line %d: Failed to set RequiredRSASize value '%ld'",
count,
l);
}
}
break;
case BIND_CFG_NOT_ALLOWED_IN_MATCH: case BIND_CFG_NOT_ALLOWED_IN_MATCH:
SSH_LOG(SSH_LOG_DEBUG, "Option not allowed in Match block: %s, line: %d", SSH_LOG(SSH_LOG_DEBUG, "Option not allowed in Match block: %s, line: %d",
keyword, count); keyword, count);

View File

@@ -636,11 +636,13 @@ SSH_PACKET_CALLBACK(channel_rcv_data)
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"Channel receiving %" PRIu32 " bytes data%s (local win=%" PRIu32 "Channel receiving %" PRIu32 " bytes data%s (local win=%" PRIu32
" remote win=%" PRIu32 ")", " remote win=%" PRIu32 ") on channel %" PRIu32 ":%" PRIu32,
len, len,
is_stderr ? " in stderr" : "", is_stderr ? " in stderr" : "",
channel->local_window, channel->local_window,
channel->remote_window); channel->remote_window,
channel->local_channel,
channel->remote_channel);
if (len > channel->local_window) { if (len > channel->local_window) {
SSH_LOG(SSH_LOG_RARE, SSH_LOG(SSH_LOG_RARE,
@@ -831,8 +833,10 @@ SSH_PACKET_CALLBACK(channel_rcv_request)
channel->exit.status = true; channel->exit.status = true;
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"received exit-status %u", "received exit-status %u on channel %" PRIu32 ":%" PRIu32,
channel->exit.code); channel->exit.code,
channel->local_channel,
channel->remote_channel);
ssh_callbacks_execute_list(channel->callbacks, ssh_callbacks_execute_list(channel->callbacks,
ssh_channel_callbacks, ssh_channel_callbacks,
@@ -1921,7 +1925,10 @@ static int channel_request(ssh_channel channel, const char *request,
} }
SSH_LOG(SSH_LOG_PACKET, SSH_LOG(SSH_LOG_PACKET,
"Sent a SSH_MSG_CHANNEL_REQUEST %s", request); "Sent a SSH_MSG_CHANNEL_REQUEST %s on channel %" PRIu32 ":%" PRIu32,
request,
channel->local_channel,
channel->remote_channel);
if (reply == 0) { if (reply == 0) {
channel->request_state = SSH_CHANNEL_REQ_STATE_NONE; channel->request_state = SSH_CHANNEL_REQ_STATE_NONE;
return SSH_OK; return SSH_OK;
@@ -1941,13 +1948,20 @@ pending:
rc=SSH_ERROR; rc=SSH_ERROR;
break; break;
case SSH_CHANNEL_REQ_STATE_DENIED: case SSH_CHANNEL_REQ_STATE_DENIED:
ssh_set_error(session, SSH_REQUEST_DENIED, ssh_set_error(session,
"Channel request %s failed", request); SSH_REQUEST_DENIED,
"Channel request %s failed on channel %" PRIu32 ":%" PRIu32,
request,
channel->local_channel,
channel->remote_channel);
rc=SSH_ERROR; rc=SSH_ERROR;
break; break;
case SSH_CHANNEL_REQ_STATE_ACCEPTED: case SSH_CHANNEL_REQ_STATE_ACCEPTED:
SSH_LOG(SSH_LOG_DEBUG, SSH_LOG(SSH_LOG_DEBUG,
"Channel request %s success",request); "Channel request %s success on channel %" PRIu32 ":%" PRIu32,
request,
channel->local_channel,
channel->remote_channel);
rc=SSH_OK; rc=SSH_OK;
break; break;
case SSH_CHANNEL_REQ_STATE_PENDING: case SSH_CHANNEL_REQ_STATE_PENDING:

View File

@@ -153,6 +153,7 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
{ "tunneldevice", SOC_NA}, { "tunneldevice", SOC_NA},
{ "xauthlocation", SOC_NA}, { "xauthlocation", SOC_NA},
{ "pubkeyacceptedkeytypes", SOC_PUBKEYACCEPTEDKEYTYPES}, { "pubkeyacceptedkeytypes", SOC_PUBKEYACCEPTEDKEYTYPES},
{ "requiredrsasize", SOC_REQUIRED_RSA_SIZE},
{ NULL, SOC_UNKNOWN } { NULL, SOC_UNKNOWN }
}; };
@@ -1439,6 +1440,12 @@ ssh_config_parse_line(ssh_session session,
ssh_options_set(session, SSH_OPTIONS_CERTIFICATE, p); ssh_options_set(session, SSH_OPTIONS_CERTIFICATE, p);
} }
break; break;
case SOC_REQUIRED_RSA_SIZE:
l = ssh_config_get_long(&s, -1);
if (l >= 0 && *parsing) {
ssh_options_set(session, SSH_OPTIONS_RSA_MIN_SIZE, &l);
}
break;
default: default:
ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d", ssh_set_error(session, SSH_FATAL, "ERROR - unimplemented opcode: %d",
opcode); opcode);

View File

@@ -166,7 +166,7 @@ int ssh_connector_set_out_channel(ssh_connector connector,
/* Fallback to default value for invalid flags */ /* Fallback to default value for invalid flags */
if (!(flags & SSH_CONNECTOR_STDOUT) && !(flags & SSH_CONNECTOR_STDERR)) { if (!(flags & SSH_CONNECTOR_STDOUT) && !(flags & SSH_CONNECTOR_STDERR)) {
connector->in_flags = SSH_CONNECTOR_STDOUT; connector->out_flags = SSH_CONNECTOR_STDOUT;
} }
return ssh_add_channel_callbacks(channel, &connector->out_channel_cb); return ssh_add_channel_callbacks(channel, &connector->out_channel_cb);
@@ -382,15 +382,13 @@ ssh_connector_fd_out_cb(ssh_connector connector)
* *
* @returns 0 * @returns 0
*/ */
static int ssh_connector_fd_cb(ssh_poll_handle p, static int ssh_connector_fd_cb(UNUSED_PARAM(ssh_poll_handle p),
socket_t fd, socket_t fd,
int revents, int revents,
void *userdata) void *userdata)
{ {
ssh_connector connector = userdata; ssh_connector connector = userdata;
(void)p;
if (revents & POLLERR) { if (revents & POLLERR) {
ssh_connector_except(connector, fd); ssh_connector_except(connector, fd);
} else if((revents & (POLLIN|POLLHUP)) && fd == connector->in_fd) { } else if((revents & (POLLIN|POLLHUP)) && fd == connector->in_fd) {
@@ -409,6 +407,10 @@ static int ssh_connector_fd_cb(ssh_poll_handle p,
* *
* @brief Callback called when data is received on channel. * @brief Callback called when data is received on channel.
* *
* @param[in] session The SSH session
*
* @param[in] channel The channel data came from
*
* @param[in] data Pointer to the data * @param[in] data Pointer to the data
* *
* @param[in] len Length of data * @param[in] len Length of data
@@ -420,7 +422,7 @@ static int ssh_connector_fd_cb(ssh_poll_handle p,
* @returns Amount of data bytes consumed * @returns Amount of data bytes consumed
*/ */
static int ssh_connector_channel_data_cb(ssh_session session, static int ssh_connector_channel_data_cb(ssh_session session,
ssh_channel channel, UNUSED_PARAM(ssh_channel channel),
void *data, void *data,
uint32_t len, uint32_t len,
int is_stderr, int is_stderr,
@@ -430,11 +432,11 @@ static int ssh_connector_channel_data_cb(ssh_session session,
int w; int w;
uint32_t window; uint32_t window;
(void) session; SSH_LOG(SSH_LOG_TRACE,
(void) channel; "Received data (%" PRIu32 ") on channel (%" PRIu32 ":%" PRIu32 ")",
(void) is_stderr; len,
channel->local_channel,
SSH_LOG(SSH_LOG_TRACE,"connector data on channel"); channel->remote_channel);
if (is_stderr && !(connector->in_flags & SSH_CONNECTOR_STDERR)) { if (is_stderr && !(connector->in_flags & SSH_CONNECTOR_STDERR)) {
/* ignore stderr */ /* ignore stderr */
@@ -448,6 +450,7 @@ static int ssh_connector_channel_data_cb(ssh_session session,
} }
if (connector->out_wontblock) { if (connector->out_wontblock) {
SSH_LOG(SSH_LOG_TRACE, "Writing won't block");
if (connector->out_channel != NULL) { if (connector->out_channel != NULL) {
uint32_t window_len; uint32_t window_len;
@@ -496,6 +499,7 @@ static int ssh_connector_channel_data_cb(ssh_session session,
return w; return w;
} else { } else {
SSH_LOG(SSH_LOG_TRACE, "Writing would block: wait?");
connector->in_available = 1; connector->in_available = 1;
return 0; return 0;
@@ -513,10 +517,11 @@ static int ssh_connector_channel_data_cb(ssh_session session,
* *
* @returns Amount of data bytes consumed * @returns Amount of data bytes consumed
*/ */
static int ssh_connector_channel_write_wontblock_cb(ssh_session session, static int
ssh_channel channel, ssh_connector_channel_write_wontblock_cb(ssh_session session,
uint32_t bytes, UNUSED_PARAM(ssh_channel channel),
void *userdata) uint32_t bytes,
void *userdata)
{ {
ssh_connector connector = userdata; ssh_connector connector = userdata;
uint8_t buffer[CHUNKSIZE]; uint8_t buffer[CHUNKSIZE];
@@ -524,7 +529,12 @@ static int ssh_connector_channel_write_wontblock_cb(ssh_session session,
(void) channel; (void) channel;
SSH_LOG(SSH_LOG_TRACE, "Channel write won't block"); SSH_LOG(SSH_LOG_TRACE,
"Write won't block (%" PRIu32 ") on channel (%" PRIu32 ":%" PRIu32 ")",
bytes,
channel->local_channel,
channel->remote_channel);
if (connector->in_available) { if (connector->in_available) {
if (connector->in_channel != NULL) { if (connector->in_channel != NULL) {
uint32_t len = MIN(CHUNKSIZE, bytes); uint32_t len = MIN(CHUNKSIZE, bytes);
@@ -535,7 +545,7 @@ static int ssh_connector_channel_write_wontblock_cb(ssh_session session,
0); 0);
if (r == SSH_ERROR) { if (r == SSH_ERROR) {
ssh_connector_except_channel(connector, connector->in_channel); ssh_connector_except_channel(connector, connector->in_channel);
} else if(r == 0 && ssh_channel_is_eof(connector->in_channel)){ } else if (r == 0 && ssh_channel_is_eof(connector->in_channel)) {
ssh_channel_send_eof(connector->out_channel); ssh_channel_send_eof(connector->out_channel);
} else if (r > 0) { } else if (r > 0) {
w = ssh_channel_write(connector->out_channel, buffer, r); w = ssh_channel_write(connector->out_channel, buffer, r);
@@ -606,15 +616,15 @@ int ssh_connector_set_event(ssh_connector connector, ssh_event event)
} }
} }
if (connector->in_channel != NULL) { if (connector->in_channel != NULL) {
rc = ssh_event_add_session(event, ssh_session session = ssh_channel_get_session(connector->in_channel);
ssh_channel_get_session(connector->in_channel)); rc = ssh_event_add_session(event, session);
if (rc != SSH_OK) if (rc != SSH_OK)
goto error; goto error;
if (ssh_channel_poll_timeout(connector->in_channel, 0, 0) > 0){ if (ssh_channel_poll_timeout(connector->in_channel, 0, 0) > 0){
connector->in_available = 1; connector->in_available = 1;
} }
} }
if(connector->out_channel != NULL) { if (connector->out_channel != NULL) {
ssh_session session = ssh_channel_get_session(connector->out_channel); ssh_session session = ssh_channel_get_session(connector->out_channel);
rc = ssh_event_add_session(event, session); rc = ssh_event_add_session(event, session);

View File

@@ -97,7 +97,7 @@ static void torture_channel_read_error(void **state) {
rc = ssh_channel_request_exec(channel, "hexdump -C /dev/urandom"); rc = ssh_channel_request_exec(channel, "hexdump -C /dev/urandom");
assert_ssh_return_code(session, rc); assert_ssh_return_code(session, rc);
/* send crap and for server to send us a disconnect */ /* send crap and wait for server to send us a disconnect */
fd = ssh_get_fd(session); fd = ssh_get_fd(session);
assert_true(fd > 2); assert_true(fd > 2);
rc = write(fd, "AAAA", 4); rc = write(fd, "AAAA", 4);

View File

@@ -239,19 +239,9 @@ void sftp_handle_session_cb(ssh_event event,
int n; int n;
int rc = 0; int rc = 0;
/* Structure for storing the pty size. */
struct winsize wsize = {
.ws_row = 0,
.ws_col = 0,
.ws_xpixel = 0,
.ws_ypixel = 0
};
/* Our struct holding information about the channel. */ /* Our struct holding information about the channel. */
struct channel_data_st cdata = { struct channel_data_st cdata = {
.event = NULL, .sftp = NULL,
.winsize = &wsize,
.sftp = NULL
}; };
/* Our struct holding information about the session. */ /* Our struct holding information about the session. */
@@ -260,7 +250,7 @@ void sftp_handle_session_cb(ssh_event event,
.auth_attempts = 0, .auth_attempts = 0,
.authenticated = 0, .authenticated = 0,
.username = SSHD_DEFAULT_USER, .username = SSHD_DEFAULT_USER,
.password = SSHD_DEFAULT_PASSWORD .password = SSHD_DEFAULT_PASSWORD,
}; };
struct ssh_channel_callbacks_struct *channel_cb = NULL; struct ssh_channel_callbacks_struct *channel_cb = NULL;
@@ -368,17 +358,11 @@ void sftp_handle_session_cb(ssh_event event,
do { do {
/* Poll the main event which takes care of the session, the channel and /* Poll the main event which takes care of the session, the channel and
* even our child process's stdout/stderr (once it's started). */ * even our child process's stdout/stderr (once it's started). */
if (ssh_event_dopoll(event, -1) == SSH_ERROR) { if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
ssh_channel_close(sdata.channel); ssh_channel_close(sdata.channel);
} }
} while (ssh_channel_is_open(sdata.channel) &&
/* If child process's stdout/stderr has been registered with the event, !ssh_channel_is_eof(sdata.channel));
* or the child process hasn't started yet, continue. */
if (cdata.event != NULL) {
continue;
}
} while (ssh_channel_is_open(sdata.channel));
ssh_channel_send_eof(sdata.channel); ssh_channel_send_eof(sdata.channel);
ssh_channel_close(sdata.channel); ssh_channel_close(sdata.channel);

View File

@@ -145,6 +145,9 @@ extern LIBSSH_THREAD int ssh_log_level;
"KexAlgorithms "KEXALGORITHMS"\n" \ "KexAlgorithms "KEXALGORITHMS"\n" \
"Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS2"\n" "Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS2"\n"
#define LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE "libssh_test_bind_config_required_rsa_size"
#define LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE_STRING "RequiredRsaSize 2233\n"
#define LIBSSH_TEST_BIND_CONFIG_FULL "libssh_test_bind_config_full" #define LIBSSH_TEST_BIND_CONFIG_FULL "libssh_test_bind_config_full"
#define LIBSSH_TEST_BIND_CONFIG_INCLUDE "libssh_test_bind_config_include" #define LIBSSH_TEST_BIND_CONFIG_INCLUDE "libssh_test_bind_config_include"
#define LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE "libssh_test_bind_config_include_recursive" #define LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE "libssh_test_bind_config_include_recursive"
@@ -298,6 +301,9 @@ static int setup_config_files(void **state)
torture_write_file(LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC, torture_write_file(LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC,
LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC_STRING); LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS_TWICE_REC_STRING);
torture_write_file(LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE,
LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE_STRING);
torture_write_file(LIBSSH_TEST_BIND_CONFIG_FULL, torture_write_file(LIBSSH_TEST_BIND_CONFIG_FULL,
"ListenAddress "LISTEN_ADDRESS"\n" "ListenAddress "LISTEN_ADDRESS"\n"
"Port 123\n" "Port 123\n"
@@ -305,7 +311,8 @@ static int setup_config_files(void **state)
"LogLevel "LOGLEVEL"\n" "LogLevel "LOGLEVEL"\n"
"Ciphers "CIPHERS"\n" "Ciphers "CIPHERS"\n"
"MACs "MACS"\n" "MACs "MACS"\n"
"KexAlgorithms "KEXALGORITHMS"\n"); "KexAlgorithms "KEXALGORITHMS"\n"
"RequiredRsaSize 2233\n");
torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE, torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE,
"Include "LIBSSH_TEST_BIND_CONFIG_LISTENADDRESS"\n" "Include "LIBSSH_TEST_BIND_CONFIG_LISTENADDRESS"\n"
@@ -314,7 +321,8 @@ static int setup_config_files(void **state)
"Include "LIBSSH_TEST_BIND_CONFIG_LOGLEVEL"\n" "Include "LIBSSH_TEST_BIND_CONFIG_LOGLEVEL"\n"
"Include "LIBSSH_TEST_BIND_CONFIG_CIPHERS"\n" "Include "LIBSSH_TEST_BIND_CONFIG_CIPHERS"\n"
"Include "LIBSSH_TEST_BIND_CONFIG_MACS"\n" "Include "LIBSSH_TEST_BIND_CONFIG_MACS"\n"
"Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS"\n"); "Include "LIBSSH_TEST_BIND_CONFIG_KEXALGORITHMS"\n"
"Include "LIBSSH_TEST_BIND_CONFIG_REQUIRED_RSA_SIZE"\n");
torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE, torture_write_file(LIBSSH_TEST_BIND_CONFIG_INCLUDE_RECURSIVE,
"Include "LIBSSH_TEST_BIND_CONFIG_INCLUDE"\n"); "Include "LIBSSH_TEST_BIND_CONFIG_INCLUDE"\n");
@@ -1410,6 +1418,8 @@ static int assert_full_bind_config(void **state)
assert_string_equal(bind->wanted_methods[SSH_KEX], KEXALGORITHMS); assert_string_equal(bind->wanted_methods[SSH_KEX], KEXALGORITHMS);
} }
assert_int_equal(bind->rsa_min_size, 2233);
SAFE_FREE(fips_ciphers); SAFE_FREE(fips_ciphers);
SAFE_FREE(fips_kex); SAFE_FREE(fips_kex);

View File

@@ -90,7 +90,8 @@ extern LIBSSH_THREAD int ssh_log_level;
"\tGSSAPIDelegateCredentials yes\n" \ "\tGSSAPIDelegateCredentials yes\n" \
"\tGSSAPIServerIdentity example.com\n" \ "\tGSSAPIServerIdentity example.com\n" \
"\tGSSAPIClientIdentity home.sweet\n" \ "\tGSSAPIClientIdentity home.sweet\n" \
"\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n" "\tUserKnownHostsFile "USER_KNOWN_HOSTS"\n" \
"\tRequiredRSASize 2233\n"
/* authentication methods */ /* authentication methods */
#define LIBSSH_TESTCONFIG_STRING8 \ #define LIBSSH_TESTCONFIG_STRING8 \
@@ -629,6 +630,7 @@ static void torture_config_new(void ** state,
assert_int_equal(ssh_get_log_level(), SSH_LOG_TRACE); assert_int_equal(ssh_get_log_level(), SSH_LOG_TRACE);
assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE); assert_int_equal(session->common.log_verbosity, SSH_LOG_TRACE);
assert_int_equal(session->opts.rsa_min_size, 2233);
} }
static void torture_config_new_file(void **state) static void torture_config_new_file(void **state)