From eeedb0cb61b8e0ca351645bdb2550937189d5116 Mon Sep 17 00:00:00 2001 From: Yucong Sun Date: Fri, 25 Oct 2019 15:40:47 -0700 Subject: [PATCH 1/7] Fix various cmake issues --- .gitignore | 4 ++-- CMakeLists.txt | 14 +++++++++++++- doc/CMakeLists.txt | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 01f9cb9..8745738 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -build/ -.vscode/ \ No newline at end of file +/build/ +/.vscode/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 17e0766..434b1ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.10) project(libtelnet VERSION 0.30.0 LANGUAGES C @@ -6,6 +6,11 @@ project(libtelnet set(PROJECT_DESCRIPTION "TELNET protocol handling library") set(PROJECT_HOMEPAGE_URL https://github.com/seanmiddleditch/libtelne) +# Enable CMAKE Policy +if(${CMAKE_VERSION} VERSION_LESS 3.10) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +endif() + if (MSVC) add_definitions(-D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS) if (LIBTELNET_STRICT) @@ -27,6 +32,13 @@ target_include_directories(libtelnet ${CMAKE_CURRENT_SOURCE_DIR} ) +find_package(ZLIB) +if(${ZLIB_FOUND}) + target_compile_definitions(libtelnet PUBLIC HAVE_ZLIB) + target_include_directories(libtelnet PRIVATE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(libtelnet PRIVATE ${ZLIB_LIBRARIES}) +endif() + add_subdirectory(util) add_subdirectory(doc) add_subdirectory(test) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 2147c1a..5e1231a 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,8 +1,8 @@ find_package(Doxygen) -add_subdirectory(man) - if (DOXYGEN_FOUND) + add_subdirectory(man) + configure_file(Doxyfile.in Doxyfile) add_custom_target(doc_doxygen ALL COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} From 7c2b801b3220c61939e51fab78eb73fffe6df4f4 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 4 Feb 2020 15:29:30 +0800 Subject: [PATCH 2/7] Don't return 1 in _environ_telnet to avoid trigger the compression and remove the redundant TELNET_TELOPT_COMPRESS2 check Signed-off-by: Xiang Xiao --- libtelnet.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libtelnet.c b/libtelnet.c index 71dc5f3..42ff040 100644 --- a/libtelnet.c +++ b/libtelnet.c @@ -553,7 +553,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, ev.type = TELNET_EV_ENVIRON; telnet->eh(telnet, &ev, telnet->ud); - return 1; + return 0; } /* very second byte must be VAR or USERVAR, if present */ @@ -657,7 +657,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, /* clean up */ free(values); - return 1; + return 0; } /* process an MSSP subnegotiation buffer */ @@ -849,17 +849,14 @@ static int _subnegotiate(telnet_t *telnet) { * start handling the compressed stream if it's not already. */ case TELNET_TELOPT_COMPRESS2: - if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS2) { - if (_init_zlib(telnet, 0, 1) != TELNET_EOK) - return 0; + if (_init_zlib(telnet, 0, 1) != TELNET_EOK) + return 0; - /* notify app that compression was enabled */ - ev.type = TELNET_EV_COMPRESS; - ev.compress.state = 1; - telnet->eh(telnet, &ev, telnet->ud); - return 1; - } - return 0; + /* notify app that compression was enabled */ + ev.type = TELNET_EV_COMPRESS; + ev.compress.state = 1; + telnet->eh(telnet, &ev, telnet->ud); + return 1; #endif /* defined(HAVE_ZLIB) */ /* specially handled subnegotiation telopt types */ From a6a5b4c35df5a0563f423c61ee3464831afea6e7 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 4 Feb 2020 15:47:31 +0800 Subject: [PATCH 3/7] Fix some wrong state handler in _negotiate Signed-off-by: Xiang Xiao --- libtelnet.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libtelnet.c b/libtelnet.c index 42ff040..1493253 100644 --- a/libtelnet.c +++ b/libtelnet.c @@ -407,7 +407,6 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_US(q), Q_YES); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL"); break; @@ -437,7 +436,8 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); + _send_negotiate(telnet, TELNET_DO, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); break; case Q_WANTYES: case Q_WANTYES_OP: @@ -465,7 +465,6 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt); _error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO"); break; @@ -491,12 +490,12 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) { break; case Q_WANTNO: _set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q)); - NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); break; case Q_WANTNO_OP: _set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q)); _send_negotiate(telnet, TELNET_WILL, telopt); - NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt); + NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt); break; case Q_WANTYES: case Q_WANTYES_OP: From c4945090c7aff4b65a351bc67ad3eee10f77438f Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 4 Feb 2020 19:55:30 +0800 Subject: [PATCH 4/7] telet-chatd handle various corner case correctly Signed-off-by: Xiang Xiao --- util/telnet-chatd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/telnet-chatd.c b/util/telnet-chatd.c index 96800fa..6afe435 100644 --- a/util/telnet-chatd.c +++ b/util/telnet-chatd.c @@ -167,6 +167,7 @@ static void _online(const char *line, size_t overflow, void *ud) { _message(user->name, "** HAS QUIT **"); free(user->name); user->name = 0; + telnet_free(user->telnet); return; } @@ -177,7 +178,7 @@ static void _online(const char *line, size_t overflow, void *ud) { static void _input(struct user_t *user, const char *buffer, size_t size) { unsigned int i; - for (i = 0; i != size; ++i) + for (i = 0; user->sock != -1 && i != size; ++i) linebuffer_push(user->linebuf, sizeof(user->linebuf), &user->linepos, (char)buffer[i], _online, user); } @@ -351,14 +352,13 @@ int main(int argc, char **argv) { } else if (rs == 0) { printf("Connection closed.\n"); close(users[i].sock); + users[i].sock = -1; if (users[i].name != 0) { _message(users[i].name, "** HAS DISCONNECTED **"); free(users[i].name); users[i].name = 0; } telnet_free(users[i].telnet); - users[i].sock = -1; - break; } else if (errno != EINTR) { fprintf(stderr, "recv(client) failed: %s\n", strerror(errno)); From 7c3f939327726c1761c12118e32623dd01f83db5 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 4 Feb 2020 23:38:47 +0800 Subject: [PATCH 5/7] Send "NVT"(network virtual terminal) as the default if getenv("TERM") return NULL Signed-off-by: Xiang Xiao --- libtelnet.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libtelnet.c b/libtelnet.c index 1493253..3d09e53 100644 --- a/libtelnet.c +++ b/libtelnet.c @@ -1609,6 +1609,9 @@ void telnet_ttype_send(telnet_t *telnet) { void telnet_ttype_is(telnet_t *telnet, const char* ttype) { static const unsigned char IS[] = { TELNET_IAC, TELNET_SB, TELNET_TELOPT_TTYPE, TELNET_TTYPE_IS }; + if (!ttype) { + ttype = "NVT"; + } _sendu(telnet, IS, sizeof(IS)); _send(telnet, ttype, strlen(ttype)); telnet_finish_sb(telnet); From 1636cf9021dd72d777427eba680c1715bdd9aed4 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 4 Feb 2020 23:45:35 +0800 Subject: [PATCH 6/7] Check POLLHUP and POLLERR in telnet poll loop to handle the remote end close correctly Signed-off-by: Xiang Xiao --- util/telnet-chatd.c | 4 ++-- util/telnet-client.c | 4 ++-- util/telnet-proxy.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/util/telnet-chatd.c b/util/telnet-chatd.c index 6afe435..12cf44a 100644 --- a/util/telnet-chatd.c +++ b/util/telnet-chatd.c @@ -308,7 +308,7 @@ int main(int argc, char **argv) { } /* new connection */ - if (pfd[MAX_USERS].revents & POLLIN) { + if (pfd[MAX_USERS].revents & (POLLIN | POLLERR | POLLHUP)) { /* acept the sock */ addrlen = sizeof(addr); if ((client_sock = accept(listen_sock, (struct sockaddr *)&addr, @@ -346,7 +346,7 @@ int main(int argc, char **argv) { if (users[i].sock == -1) continue; - if (pfd[i].revents & POLLIN) { + if (pfd[i].revents & (POLLIN | POLLERR | POLLHUP)) { if ((rs = recv(users[i].sock, buffer, sizeof(buffer), 0)) > 0) { telnet_recv(users[i].telnet, buffer, rs); } else if (rs == 0) { diff --git a/util/telnet-client.c b/util/telnet-client.c index aff4558..5c0a7f8 100644 --- a/util/telnet-client.c +++ b/util/telnet-client.c @@ -225,7 +225,7 @@ int main(int argc, char **argv) { /* loop while both connections are open */ while (poll(pfd, 2, -1) != -1) { /* read from stdin */ - if (pfd[0].revents & POLLIN) { + if (pfd[0].revents & (POLLIN | POLLERR | POLLHUP)) { if ((rs = read(STDIN_FILENO, buffer, sizeof(buffer))) > 0) { _input(buffer, rs); } else if (rs == 0) { @@ -238,7 +238,7 @@ int main(int argc, char **argv) { } /* read from client */ - if (pfd[1].revents & POLLIN) { + if (pfd[1].revents & (POLLIN | POLLERR | POLLHUP)) { if ((rs = recv(sock, buffer, sizeof(buffer), 0)) > 0) { telnet_recv(telnet, buffer, rs); } else if (rs == 0) { diff --git a/util/telnet-proxy.c b/util/telnet-proxy.c index 32d393d..16d8a33 100644 --- a/util/telnet-proxy.c +++ b/util/telnet-proxy.c @@ -464,7 +464,7 @@ int main(int argc, char **argv) { /* loop while both connections are open */ while (poll(pfd, 2, -1) != -1) { /* read from server */ - if (pfd[0].revents & POLLIN) { + if (pfd[0].revents & (POLLIN | POLLERR | POLLHUP)) { if ((rs = recv(server.sock, buffer, sizeof(buffer), 0)) > 0) { telnet_recv(server.telnet, buffer, rs); } else if (rs == 0) { @@ -480,7 +480,7 @@ int main(int argc, char **argv) { } /* read from client */ - if (pfd[1].revents & POLLIN) { + if (pfd[1].revents & (POLLIN | POLLERR | POLLHUP)) { if ((rs = recv(client.sock, buffer, sizeof(buffer), 0)) > 0) { telnet_recv(client.telnet, buffer, rs); } else if (rs == 0) { From 88297d4681eeca3bbb68836dbf39c8b645867ed7 Mon Sep 17 00:00:00 2001 From: Yucong Sun Date: Wed, 5 Feb 2020 10:54:30 -0800 Subject: [PATCH 7/7] Update ci.yml --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 578d567..6b13f74 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,9 @@ on: - master - develop pull_request: + branches: + - master + - develop jobs: Build: