Hello community, here is the log from the commit of package uftpd for openSUSE:Factory checked in at 2020-01-05 15:22:47 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/uftpd (Old) and /work/SRC/openSUSE:Factory/.uftpd.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "uftpd" Sun Jan 5 15:22:47 2020 rev:8 rq:760936 version:2.11 Changes: -------- --- /work/SRC/openSUSE:Factory/uftpd/uftpd.changes 2019-08-27 10:27:48.227912562 +0200 +++ /work/SRC/openSUSE:Factory/.uftpd.new.6675/uftpd.changes 2020-01-05 15:22:49.657611262 +0100 @@ -1,0 +2,12 @@ +Sun Jan 5 09:44:30 UTC 2020 - Martin Hauke <[email protected]> + +- Update to version 2.11 + * Increased logging at default log level. Now all relevant + interaction is logged. See the man page for how to adjust. + * Fix buffer overflow in FTP PORT parser + * Fix TFTP/FTP directory traversal regression + * Fix potential DOS through non-busy loop and segfault + * Fix potential segfault through empty FTP password + * Fix potential segfault through FTP PORT command + +------------------------------------------------------------------- Old: ---- uftpd-2.10.tar.gz New: ---- uftpd-2.11.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ uftpd.spec ++++++ --- /var/tmp/diff_new_pack.Z0iMcQ/_old 2020-01-05 15:22:50.089611478 +0100 +++ /var/tmp/diff_new_pack.Z0iMcQ/_new 2020-01-05 15:22:50.093611480 +0100 @@ -1,7 +1,7 @@ # # spec file for package uftpd # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2018, Martin Hauke <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -18,7 +18,7 @@ Name: uftpd -Version: 2.10 +Version: 2.11 Release: 0 Summary: A combined TFTP/FTP server License: ISC ++++++ uftpd-2.10.tar.gz -> uftpd-2.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/ChangeLog.md new/uftpd-2.11/ChangeLog.md --- old/uftpd-2.10/ChangeLog.md 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/ChangeLog.md 2020-01-05 08:51:54.000000000 +0100 @@ -4,6 +4,22 @@ All notable changes to the project are documented in this file. +[v2.11][] - 2020-01-05 +---------------------- + +### Changes +- Increased logging at default log level. Now users logging in, + downloading, uploading, directory creation/removal is logged by + default. Start with `-l error` to silence uftpd again + +### Fixes +- Fix buffer overflow in FTP PORT parser, reported by Aaron Esau +- Fix TFTP/FTP directory traversal regression , reported by Aaron Esau +- Fix potential DOS through non-busy loop and segfault, by Aaron Esau +- Fix potential segfault through empty FTP password, by Aaron Esau +- Fix potential segfault through FTP PORT command, by Aaron Esau + + [v2.10][] - 2019-08-15 ---------------------- @@ -436,7 +452,8 @@ Lines must end in the old `\r\n` format, rather than UNIX `\n`. -[UNRELEASED]: https://github.com/troglobit/uftpd/compare/v2.10...HEAD +[UNRELEASED]: https://github.com/troglobit/uftpd/compare/v2.11...HEAD +[v2.11]: https://github.com/troglobit/uftpd/compare/v2.10...v2.11 [v2.10]: https://github.com/troglobit/uftpd/compare/v2.9...v2.10 [v2.9]: https://github.com/troglobit/uftpd/compare/v2.8...v2.9 [v2.8]: https://github.com/troglobit/uftpd/compare/v2.7...v2.8 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/README.md new/uftpd-2.11/README.md --- old/uftpd-2.10/README.md 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/README.md 2020-01-05 08:51:54.000000000 +0100 @@ -25,7 +25,7 @@ uftpd [-hnsv] [-l LEVEL] [-o ftp=PORT,tftp=PORT,writable] [PATH] -h Show this help text - -l LEVEL Set log level: none, err, info, notice (default), debug + -l LEVEL Set log level: none, err, notice (default), info, debug -n Run in foreground, do not detach from controlling terminal -o OPT Options: ftp=PORT @@ -63,6 +63,9 @@ uftpd -o writable PATH +> **Note:** since v2.11 uftpd logs a lot more events by default. Set up +> your syslogd to redirect `LOG_FTP` to a separate log file, or reduce +> the log level of uftpd using `-l error` to only log errors and higher. Running from inetd ------------------ @@ -88,7 +91,7 @@ Caveat ------ -uftpd is primarily not targetted at secure installations, it is targeted +uftpd is primarily not targeted at secure installations, it is targeted at users in need of a *simple* FTP/TFTP server. uftpd allows symlinks outside the FTP root, as well as a group writable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/configure.ac new/uftpd-2.11/configure.ac --- old/uftpd-2.10/configure.ac 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/configure.ac 2020-01-05 08:51:54.000000000 +0100 @@ -1,4 +1,4 @@ -AC_INIT([uftpd], [2.10], [https://github.com/troglobit/uftpd/issues],, +AC_INIT([uftpd], [2.11], [https://github.com/troglobit/uftpd/issues],, [https://troglobit.com/projects/uftpd/]) AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) AM_SILENT_RULES([yes]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/debian/changelog new/uftpd-2.11/debian/changelog --- old/uftpd-2.10/debian/changelog 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/debian/changelog 2020-01-05 08:51:54.000000000 +0100 @@ -1,3 +1,15 @@ +uftpd (2.11) unstable; urgency=medium + + * Increased logging at default log level. Now all relevant interaction + is logged. See the man page for how to adjust. + * Fix buffer overflow in FTP PORT parser + * Fix TFTP/FTP directory traversal regression + * Fix potential DOS through non-busy loop and segfault + * Fix potential segfault through empty FTP password + * Fix potential segfault through FTP PORT command + + -- Joachim Nilsson <[email protected]> Sun, 05 Jan 2020 08:49:56 +0100 + uftpd (2.10) unstable; urgency=medium * Add support for TFTP WRQ, i.e. for clients sending files to server diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/man/uftpd.8 new/uftpd-2.11/man/uftpd.8 --- old/uftpd-2.10/man/uftpd.8 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/man/uftpd.8 2020-01-05 08:51:54.000000000 +0100 @@ -41,8 +41,7 @@ .Nm this means listen to port 21 (FTP) and port 69 (TFTP), serve files from .Pa /srv/ftp , -and log anything out of the ordinary to syslog. Messages are written to -the syslog using the +and log to syslog. Messages are written to the syslog using the .Nm LOG_FTP facility. .Pp @@ -51,15 +50,24 @@ .It Fl h Show built-in help text .It Fl l Ar LOG -Set log level: none, err, info, +Set log level: none, err, .Ar notice , -debug +info, debug. By default the log level is +.Ar notice , +which is less verbose than +.Ar info , +but still logs all relevant events: users logging in, uploading, +downloading, creating and removing directories, etc. To reduce +the log level, start +.Nm +with +.Cm Fl l Ar error . .It Fl n Run in foreground, do not detach from controlling terminal .It Fl o Set .Nm -option, seprate multiple options with comma: +option, separate multiple options with comma: .Bl -tag .It Ar ftp=PORT .It Ar tftp=PORT @@ -177,10 +185,10 @@ .It Sy Request Ta Sy Description .It RRQ Ta Read Request for file, may have options .It WRQ Ta Write Request for file, may have options -.It DATA Ta File data, preceeded by block n:o +.It DATA Ta File data, preceded by block n:o .It ERROR Ta Error, end of session .It ACK Ta ACKnowledge DATA or WRQ without options -.It OACK Ta Option acknowleged, sent as response to RRQ/WRQ +.It OACK Ta Option acknowledged, sent as response to RRQ/WRQ .El .Pp .Nm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/src/common.c new/uftpd-2.11/src/common.c --- old/uftpd-2.10/src/common.c 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/src/common.c 2020-01-05 08:51:54.000000000 +0100 @@ -87,16 +87,20 @@ return NULL; } + DBG("realpath(%s) => %s", ptr, rpath); + if (rpath[1] != 0) strlcat(rpath, "/", sizeof(rpath)); strlcat(rpath, name, sizeof(rpath)); } - if (!chrooted && strncmp(dir, home, strlen(home))) { + if (!chrooted && strncmp(rpath, home, strlen(home))) { DBG("Failed non-chroot dir:%s vs home:%s", dir, home); return NULL; } + DBG("Final path to file: %s", rpath); + return rpath; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/src/ftpcmd.c new/uftpd-2.11/src/ftpcmd.c --- old/uftpd-2.10/src/ftpcmd.c 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/src/ftpcmd.c 2020-01-05 08:51:54.000000000 +0100 @@ -333,6 +333,11 @@ return; } + if (!pass) { + send_msg(ctrl->sd, "503 No password given.\r\n"); + return; + } + strlcpy(ctrl->pass, pass, sizeof(ctrl->pass)); if (check_user_pass(ctrl) < 0) { LOG("User %s from %s, invalid password!", ctrl->name, ctrl->clientaddr); @@ -439,9 +444,14 @@ ctrl->data_sd = -1; } + if (!str) { + send_msg(ctrl->sd, "500 No PORT specified.\r\n"); + return; + } + /* Convert PORT command's argument to IP address + port */ sscanf(str, "%d,%d,%d,%d,%d,%d", &a, &b, &c, &d, &e, &f); - sprintf(addr, "%d.%d.%d.%d", a, b, c, d); + snprintf(addr, sizeof(addr), "%d.%d.%d.%d", a, b, c, d); /* Check IPv4 address using inet_aton(), throw away converted result */ if (!inet_aton(addr, &(sin.sin_addr))) { @@ -773,10 +783,11 @@ char *ptr2; ptr2 = strchr("[1], '"'); - if (ptr2) { - memmove(ptr2, &ptr2[1], strlen(ptr2)); - memmove(quot, "[1], strlen(quot)); - } + if (!ptr2) + break; + + memmove(ptr2, &ptr2[1], strlen(ptr2)); + memmove(quot, "[1], strlen(quot)); } arg = ptr; } @@ -920,7 +931,7 @@ return 1; } - INFO("Data server port estabished. Waiting for client to connect ..."); + INFO("Data server port established. Waiting for client to connect ..."); if (listen(ctrl->data_listen_sd, 1) < 0) { ERR(errno, "Client data connection failure"); send_msg(ctrl->sd, "426 Internal server error.\r\n"); @@ -1010,7 +1021,7 @@ num = fread(buf, sizeof(char), sizeof(buf), ctrl->fp); if (!num) { if (feof(ctrl->fp)) - INFO("User %s from %s downloaded %s", ctrl->name, ctrl->clientaddr, ctrl->file); + LOG("User %s from %s downloaded '%s'", ctrl->name, ctrl->clientaddr, ctrl->file); else if (ferror(ctrl->fp)) ERR(0, "Error while reading %s", ctrl->file); do_abort(ctrl); @@ -1090,7 +1101,13 @@ struct stat st; path = compose_abspath(ctrl, file); - if (!path || stat(path, &st) || !S_ISREG(st.st_mode)) { + if (!path || stat(path, &st)) { + LOG("%s: Failed opening '%s'. No such file or directory", ctrl->clientaddr, path); + send_msg(ctrl->sd, "550 No such file or directory.\r\n"); + return; + } + if (!S_ISREG(st.st_mode)) { + LOG("%s: Failed opening '%s'. Not a regular file", ctrl->clientaddr, path); send_msg(ctrl->sd, "550 Not a regular file.\r\n"); return; } @@ -1124,6 +1141,7 @@ do_PORT(ctrl, 2); } +/* Request to set mtime, ncftp does this */ static void handle_MDTM(ctrl_t *ctrl, char *file) { struct stat st; @@ -1132,16 +1150,19 @@ char *mtime = NULL; char buf[80]; - /* Request to set mtime, ncftp does this */ + if (!file) + goto missing; + ptr = strchr(file, ' '); if (ptr) { *ptr++ = 0; mtime = file; file = ptr; - } + } path = compose_abspath(ctrl, file); if (!path || stat(path, &st) || !S_ISREG(st.st_mode)) { + missing: send_msg(ctrl->sd, "550 Not a regular file.\r\n"); return; } @@ -1166,6 +1187,8 @@ ERR(errno, "Failed setting MTIME %s of %s", mtime, file); goto fail; } + + LOG("User %s from %s changed mtime of %s", ctrl->name, ctrl->clientaddr, file); (void)stat(path, &st); } @@ -1208,7 +1231,7 @@ return; } if (bytes == 0) { - INFO("User %s at %s uploaded file %s", ctrl->name, ctrl->clientaddr, ctrl->file); + LOG("User %s from %s uploaded file %s", ctrl->name, ctrl->clientaddr, ctrl->file); do_abort(ctrl); send_msg(ctrl->sd, "226 Transfer complete.\r\n"); return; @@ -1283,11 +1306,14 @@ fail: send_msg(ctrl->sd, "550 No such file or directory.\r\n"); else if (EPERM == errno) send_msg(ctrl->sd, "550 Not allowed to remove file or directory.\r\n"); + else if (ENOTEMPTY == errno) + send_msg(ctrl->sd, "550 Not allowed to remove directory, not empty.\r\n"); else send_msg(ctrl->sd, "550 Unknown error.\r\n"); return; } + LOG("User %s from %s deleted %s", ctrl->name, ctrl->clientaddr, file); send_msg(ctrl->sd, "200 Command OK\r\n"); } @@ -1309,6 +1335,7 @@ return; } + LOG("User %s from %s created directory %s", ctrl->name, ctrl->clientaddr, arg); send_msg(ctrl->sd, "200 Command OK\r\n"); } @@ -1411,7 +1438,7 @@ static void handle_OPTS(ctrl_t *ctrl, char *arg) { /* OPTS MLST type;size;modify;perm; */ - if (strstr(arg, "MLST")) { + if (arg && strstr(arg, "MLST")) { size_t i = 0; char *ptr; char buf[42] = "200 MLST OPTS "; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/src/tftpcmd.c new/uftpd-2.11/src/tftpcmd.c --- old/uftpd-2.10/src/tftpcmd.c 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/src/tftpcmd.c 2020-01-05 08:51:54.000000000 +0100 @@ -220,7 +220,7 @@ ctrl->fp = fopen(path, "r"); if (!ctrl->fp) { - ERR(errno, "%s: Failed opening %s", ctrl->clientaddr, path); + ERR(errno, "%s: Failed opening '%s'", ctrl->clientaddr, path); return send_ERROR(ctrl, ENOTFOUND, NULL); } @@ -240,7 +240,7 @@ ctrl->offset = 1; /* First expected block */ ctrl->fp = fopen(path, "w"); if (!ctrl->fp) { - ERR(errno, "%s: Failed opening %s", ctrl->clientaddr, path); + ERR(errno, "%s: Failed opening '%s'", ctrl->clientaddr, path); return send_ERROR(ctrl, ENOTFOUND, NULL); } @@ -328,7 +328,7 @@ active = 0; break; } - DBG("tftp RRQ %s from %s:%d", ctrl->file, ctrl->clientaddr, port); + LOG("tftp RRQ '%s' from %s:%d", ctrl->file, ctrl->clientaddr, port); active = handle_RRQ(ctrl); free(ctrl->file); break; @@ -340,13 +340,13 @@ active = 0; break; } - DBG("tftp WRQ %s from %s:%d", ctrl->file, ctrl->clientaddr, port); + LOG("tftp WRQ '%s' from %s:%d", ctrl->file, ctrl->clientaddr, port); handle_WRQ(ctrl); free(ctrl->file); break; case DATA: /* Received data after WRQ */ - DBG("tftp DATA %s from %s:%d", ctrl->file, ctrl->clientaddr, port); + INFO("tftp DATA '%s' from %s:%d", ctrl->file, ctrl->clientaddr, port); len -= ctrl->th->th_data - ctrl->buf; active = handle_DATA(ctrl, len); break; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/uftpd-2.10/src/uftpd.c new/uftpd-2.11/src/uftpd.c --- old/uftpd-2.10/src/uftpd.c 2019-08-15 09:20:03.000000000 +0200 +++ new/uftpd-2.11/src/uftpd.c 2020-01-05 08:51:54.000000000 +0100 @@ -55,7 +55,7 @@ printf("\nUsage: %s [-hnsv] [-l LEVEL] [-o ftp=PORT,tftp=PORT,writable] [PATH]\n\n", prognm); printf(" -h Show this help text\n" - " -l LEVEL Set log level: none, err, info, notice (default), debug\n"); + " -l LEVEL Set log level: none, err, notice (default), info, debug\n"); if (!is_inetd) printf(" -n Run in foreground, do not detach from controlling terminal\n" " -o OPT Options:\n"
