From 07f1f1d5f9876d10870c672e99df3e8c1ca7c7b4 Mon Sep 17 00:00:00 2001 From: clearrml Date: Sun, 22 Dec 2024 17:07:32 +0200 Subject: [PATCH] sync_git_2024.86 tag/DROPBEAR_2024.86 --- src/cli-readconf.c | 3 ++- src/common-channel.c | 3 ++- src/svr-auth.c | 3 ++- src/svr-main.c | 2 +- src/sysoptions.h | 2 +- test/requirements.txt | 12 ++++++------ test/test_channels.py | 4 ++-- test/test_concurrent.py | 34 ++++++++++++++++++++++++++++++++++ 8 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 test/test_concurrent.py diff --git a/src/cli-readconf.c b/src/cli-readconf.c index 22af7c7..05fae6b 100644 --- a/src/cli-readconf.c +++ b/src/cli-readconf.c @@ -69,7 +69,8 @@ void read_config_file(char* filename, FILE* config_file, cli_runopts* options) { while (buf_getline(buf, config_file) == DROPBEAR_SUCCESS) { char* commentStart = NULL; cfg_option cfg_opt; - int found, i; + int found; + size_t i; /* Update line number counter. */ linenum++; diff --git a/src/common-channel.c b/src/common-channel.c index be5b57f..9926972 100644 --- a/src/common-channel.c +++ b/src/common-channel.c @@ -317,7 +317,8 @@ static void check_close(struct Channel *channel) { if ((channel->recv_eof && !write_pending(channel)) /* have a server "session" and child has exited */ - || (channel->type->check_close && close_allowed)) { + || (channel->writefd != FD_UNINIT + && channel->type->check_close && close_allowed)) { close_chan_fd(channel, channel->writefd, SHUT_WR); } diff --git a/src/svr-auth.c b/src/svr-auth.c index aa0ac4a..6b9eb4b 100644 --- a/src/svr-auth.c +++ b/src/svr-auth.c @@ -337,7 +337,8 @@ static int checkusername(const char *username, unsigned int userlen) { if (!ses.authstate.pw_name) { TRACE(("leave checkusername: user '%s' doesn't exist", username)) dropbear_log(LOG_WARNING, - "Login attempt for nonexistent user"); + "Login attempt for nonexistent user from %s", + svr_ses.addrstring); ses.authstate.checkusername_failed = 1; return DROPBEAR_FAILURE; } diff --git a/src/svr-main.c b/src/svr-main.c index 86d0db2..6373e59 100644 --- a/src/svr-main.c +++ b/src/svr-main.c @@ -226,7 +226,7 @@ static void main_noinetd(int argc, char ** argv, const char* multipath) { if (ses.exitflag) { unlink(svr_opts.pidfile); - dropbear_exit("Terminated by signal"); + dropbear_close("Terminated by signal"); } if (val == 0) { diff --git a/src/sysoptions.h b/src/sysoptions.h index 0533c6e..9b325d5 100644 --- a/src/sysoptions.h +++ b/src/sysoptions.h @@ -4,7 +4,7 @@ *******************************************************************/ #ifndef DROPBEAR_VERSION -#define DROPBEAR_VERSION "2024.85" +#define DROPBEAR_VERSION "2024.86" #endif /* IDENT_VERSION_PART is the optional part after "SSH-2.0-dropbear". Refer to RFC4253 for requirements. */ diff --git a/test/requirements.txt b/test/requirements.txt index 50e8214..599a05f 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,9 +1,9 @@ attrs==21.2.0 -iniconfig==1.1.1 -packaging==21.0 -pluggy==1.0.0 -py==1.10.0 +iniconfig==2.0.0 +packaging==24.1 +pluggy==1.5.0 +psutil==6.0.0 pyparsing==2.4.7 -pytest==6.2.5 +pytest==8.3.2 toml==0.10.2 -psutil==5.9.0 +asyncssh==2.17.0 diff --git a/test/test_channels.py b/test/test_channels.py index 9c493ad..d6feb04 100644 --- a/test/test_channels.py +++ b/test/test_channels.py @@ -69,9 +69,9 @@ def test_bg_sleep(request, fd, dropbear): def test_idle(request, dropbear): - # Idle test, -I 1 should make it return before the 2 second timeout + # Idle test, -I 1 should make it return before the 5 second timeout r = dbclient(request, "-I", "1", "echo zong; sleep 10", - capture_output=True, timeout=2, text=True) + capture_output=True, timeout=5, text=True) r.check_returncode() assert r.stdout.rstrip() == "zong" diff --git a/test/test_concurrent.py b/test/test_concurrent.py new file mode 100644 index 0000000..b0d16f1 --- /dev/null +++ b/test/test_concurrent.py @@ -0,0 +1,34 @@ +""" +Tests opening and closing several (up to 4) channels concurrently. +""" +from test_dropbear import * + +import asyncssh +import asyncio +import random + +async def run(addr, port): + async with asyncssh.connect(addr, port = port) as conn: + + chans = [] + MAX=4 + + for x in range(10000): + if len(chans) < MAX: + pipes = await conn.open_session(command = "df") + chans.append(pipes) + l = len(chans) + print(f" add, len {l}") + + if random.random() < 0.2: + i = random.randrange(0, len(chans)) + l = len(chans) + print(f" del {i}/{l}") + del chans[i] + +def test_concurrent(request, dropbear): + opt = request.config.option + host = opt.remote or LOCALADDR + port = int(opt.port) + + asyncio.run(run(host, port))