# HG changeset patch # User Jiri Sasek # Date 1461655691 25200 # Node ID 0f3d50fefade583f5b5a41b97e4a0b7715db4d0c # Parent 986a46fa92f7fecf939716505d525c018955c28b 23124279 ProFTPd: Update to 1.3.5b 22202943 ProFTPD Version 1.3.5 returns wrong error code upon re-authentication 22923893 problem in SERVICE/PROFTPD 22919363 problem in SERVICE/PROFTPD diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/Makefile --- a/components/proftpd/Makefile Wed Apr 27 13:38:51 2016 -0700 +++ b/components/proftpd/Makefile Tue Apr 26 00:28:11 2016 -0700 @@ -27,15 +27,16 @@ COMPONENT_NAME= proftpd COMPONENT_VERSION= 1.3.5 -COMPONENT_SUBVERSION= +COMPONENT_SUBVERSION= b HUMAN_VERSION= $(COMPONENT_VERSION)$(COMPONENT_SUBVERSION) COMPONENT_PROJECT_URL= http://www.proftpd.org/ COMPONENT_SRC= $(COMPONENT_NAME)-$(HUMAN_VERSION) COMPONENT_ARCHIVE= $(COMPONENT_SRC).tar.gz COMPONENT_ARCHIVE_HASH= \ - sha256:c10316fb003bd25eccbc08c77dd9057e053693e6527ffa2ea2cc4e08ccb87715 + sha256:afc1789f2478acf88dfdc7d70da90a4fa2786d628218e9574273295d044b4fc8 COMPONENT_ARCHIVE_URL= ftp://ftp.proftpd.org/distrib/source/$(COMPONENT_ARCHIVE) COMPONENT_BUGDB= service/proftpd +TPNO_PROFTPD= 27604 # mod_gss subcomponent COMPONENT_NAME_1= mod_gss @@ -45,8 +46,6 @@ COMPONENT_ARCHIVE_HASH_1= \ sha256:bd1cb3f8ba0668981beb54d8b4de10ab204199327a464debd9da19196bbb23c4 COMPONENT_ARCHIVE_URL_1= http://downloads.sourceforge.net/gssmod/$(COMPONENT_ARCHIVE_1) - -TPNO_PROFTPD= 17783 TPNO_MOD_GSS= 13480 # libcheck and specific Perl Test::Unit version is required for full test diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/004.proftpd-retry.patch --- a/components/proftpd/patches/004.proftpd-retry.patch Wed Apr 27 13:38:51 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ ---- a/src/data.c -+++ b/src/data.c -@@ -337,6 +337,7 @@ static int data_pasv_open(char *reason, off_t size) { - static int data_active_open(char *reason, off_t size) { - conn_t *c; - int bind_port, rev; -+ int retries = 0; - pr_netaddr_t *bind_addr; - unsigned char *root_revoke = NULL; - -@@ -368,7 +369,9 @@ static int data_active_open(char *reason, off_t size) { - bind_port = INPORT_ANY; - } - -- session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port, TRUE); -+ for (;;) { -+ session.d = pr_inet_create_conn(session.pool, -1, bind_addr, bind_port, -+ TRUE); - - /* Default remote address to which to connect for an active transfer, - * if the client has not specified a different address via PORT/EPRT, -@@ -416,6 +419,15 @@ static int data_active_open(char *reason, off_t size) { - - if (pr_inet_connect(session.d->pool, session.d, &session.data_addr, - session.data_port) == -1) { -+ -+ if (session.d->xerrno == EADDRINUSE && retries < 16) { -+ destroy_pool(session.d->pool); -+ pr_signals_handle(); -+ /* Wait up to MSL to avoid TIME_WAIT. */ -+ sleep(retries++); -+ continue; -+ } -+ - pr_log_debug(DEBUG6, - "Error connecting to %s#%u for active data transfer: %s", - pr_netaddr_get_ipstr(&session.data_addr), session.data_port, -@@ -427,6 +439,9 @@ static int data_active_open(char *reason, off_t size) { - destroy_pool(session.d->pool); - session.d = NULL; - return -1; -+ } else -+ break; -+ - } - - c = pr_inet_openrw(session.pool, session.d, NULL, PR_NETIO_STRM_DATA, - diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/005.proftpd-error_code.patch --- a/components/proftpd/patches/005.proftpd-error_code.patch Wed Apr 27 13:38:51 2016 -0700 +++ b/components/proftpd/patches/005.proftpd-error_code.patch Tue Apr 26 00:28:11 2016 -0700 @@ -1,18 +1,3 @@ -diff --git a/include/dirtree.h b/include/dirtree.h -index 0f41986..fe7b14b 100644 ---- a/include/dirtree.h -+++ b/include/dirtree.h -@@ -126,6 +126,10 @@ typedef struct cmd_struc { - pr_table_t *notes; /* Private data for passing/retaining between handlers */ - - int cmd_id; /* Index into commands list, for faster comparisons */ -+ -+ int error_code; /* Stores errno of failed file transfer -+ * commands. Required for Solaris auditing. -+ */ - } cmd_rec; - - struct config_struc { diff --git a/modules/mod_core.c b/modules/mod_core.c index e33ee11..f680748 100644 --- a/modules/mod_core.c @@ -154,11 +139,9 @@ pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); -diff --git a/modules/mod_xfer.c b/modules/mod_xfer.c -index bcfb487..41c597e 100644 ---- a/modules/mod_xfer.c -+++ b/modules/mod_xfer.c -@@ -1190,6 +1190,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +--- a/modules/mod_xfer.c 2016-03-10 17:04:32.000000000 -0800 ++++ proftpd-1.3.5b/modules/mod_xfer.c 2016-04-01 01:54:06.383804153 -0700 +@@ -1187,6 +1187,7 @@ if (cmd->argc < 2) { pr_response_add_err(R_500, _("'%s' not understood"), pr_cmd_get_displayable_str(cmd, NULL)); @@ -166,7 +149,7 @@ errno = EINVAL; return PR_ERROR(cmd); } -@@ -1200,6 +1201,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1197,6 +1198,7 @@ if (!path || !dir_check(cmd->tmp_pool, cmd, cmd->group, path, NULL)) { int xerrno = errno; @@ -174,7 +157,7 @@ pr_log_debug(DEBUG8, "%s %s denied by configuration", cmd->argv[0], cmd->arg); -@@ -1232,6 +1234,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1229,6 +1231,7 @@ if (xfer_check_limit(cmd) < 0) { pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg); errno = EPERM; @@ -182,7 +165,7 @@ return PR_ERROR(cmd); } -@@ -1244,6 +1247,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1241,6 +1244,7 @@ pr_log_debug(DEBUG6, "AllowOverwrite denied permission for %s", cmd->arg); pr_response_add_err(R_550, _("%s: Overwrite permission denied"), cmd->arg); errno = EACCES; @@ -190,7 +173,7 @@ return PR_ERROR(cmd); } -@@ -1267,6 +1271,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1264,6 +1268,7 @@ /* Deliberately use EISDIR for anything non-file (e.g. directories). */ errno = EISDIR; @@ -198,7 +181,7 @@ return PR_ERROR(cmd); } } -@@ -1285,6 +1290,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1282,6 +1287,7 @@ session.restart_pos = 0L; session.xfer.xfer_type = STOR_DEFAULT; errno = EPERM; @@ -206,7 +189,7 @@ return PR_ERROR(cmd); } -@@ -1306,6 +1312,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1303,6 +1309,7 @@ /* Otherwise everthing is good */ if (pr_table_add(cmd->notes, "mod_xfer.store-path", pstrdup(cmd->pool, path), 0) < 0) { @@ -214,7 +197,7 @@ if (errno != EEXIST) { pr_log_pri(PR_LOG_NOTICE, "notice: error adding 'mod_xfer.store-path': %s", strerror(errno)); -@@ -1326,6 +1333,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1323,6 +1330,7 @@ pr_response_add_err(R_501, _("REST not compatible with server configuration")); errno = EINVAL; @@ -222,7 +205,7 @@ return PR_ERROR(cmd); } -@@ -1335,6 +1343,7 @@ MODRET xfer_pre_stor(cmd_rec *cmd) { +@@ -1332,6 +1340,7 @@ pr_response_add_err(R_550, _("APPE not compatible with server configuration")); errno = EINVAL; @@ -230,23 +213,23 @@ return PR_ERROR(cmd); } -@@ -1400,6 +1409,7 @@ MODRET xfer_pre_stou(cmd_rec *cmd) { - tmpfd = mkstemp(filename); - if (tmpfd < 0) { +@@ -1398,6 +1407,7 @@ + stou_fd = mkstemp(filename); + if (stou_fd < 0) { int xerrno = errno; + cmd->error_code = errno; pr_log_pri(PR_LOG_WARNING, "error: unable to use mkstemp(): %s", strerror(xerrno)); -@@ -1428,6 +1438,7 @@ MODRET xfer_pre_stou(cmd_rec *cmd) { - if (!filename || +@@ -1426,6 +1436,7 @@ + if (filename == NULL || !dir_check(cmd->tmp_pool, cmd, cmd->group, filename, NULL)) { int xerrno = errno; + cmd->error_code = errno; /* Do not forget to delete the file created by mkstemp(3) if there is * an error. -@@ -1461,12 +1472,14 @@ MODRET xfer_pre_stou(cmd_rec *cmd) { +@@ -1459,12 +1470,14 @@ /* Deliberately use EISDIR for anything non-file (e.g. directories). */ errno = EISDIR; @@ -261,15 +244,16 @@ if (errno != EEXIST) { pr_log_pri(PR_LOG_NOTICE, "notice: error adding 'mod_xfer.store-path': %s", strerror(errno)); -@@ -1492,6 +1505,7 @@ MODRET xfer_post_stou(cmd_rec *cmd) { - mode_t mode = 0666; +@@ -1499,6 +1512,8 @@ + perms = (0666 & ~mask); - if (pr_fsio_chmod(cmd->arg, mode) < 0) { + if (pr_fsio_chmod(cmd->arg, perms) < 0) { + cmd->error_code = errno; - ++ /* Not much to do but log the error. */ pr_log_pri(PR_LOG_NOTICE, "error: unable to chmod '%s' to %04o: %s", -@@ -1510,6 +1524,7 @@ MODRET xfer_pre_appe(cmd_rec *cmd) { + cmd->arg, perms, strerror(errno)); +@@ -1516,6 +1531,7 @@ if (xfer_check_limit(cmd) < 0) { pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg); errno = EPERM; @@ -277,7 +261,7 @@ return PR_ERROR(cmd); } -@@ -1580,6 +1595,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1586,6 +1602,7 @@ if (stor_fh) { if (pr_fsio_lseek(stor_fh, 0, SEEK_END) == (off_t) -1) { @@ -285,7 +269,7 @@ pr_log_debug(DEBUG4, "unable to seek to end of '%s' for appending: %s", cmd->arg, strerror(errno)); (void) pr_fsio_close(stor_fh); -@@ -1588,6 +1604,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1594,6 +1611,7 @@ } else { ferrno = errno; @@ -293,7 +277,7 @@ (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): " "error opening '%s': %s", cmd->argv[0], session.user, -@@ -1601,6 +1618,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1607,6 +1625,7 @@ O_WRONLY|(session.restart_pos ? 0 : O_TRUNC|O_CREAT)); if (stor_fh == NULL) { ferrno = errno; @@ -301,7 +285,7 @@ (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): " "error opening '%s': %s", cmd->argv[0], session.user, -@@ -1614,11 +1632,13 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1620,11 +1639,13 @@ int xerrno = 0; if (pr_fsio_lseek(stor_fh, session.restart_pos, SEEK_SET) == -1) { @@ -315,7 +299,7 @@ pr_log_debug(DEBUG4, "unable to stat '%s': %s", cmd->arg, strerror(errno)); xerrno = errno; -@@ -1755,6 +1775,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1761,6 +1782,7 @@ pr_data_abort(EPERM, FALSE); errno = EPERM; #endif @@ -323,7 +307,7 @@ return PR_ERROR(cmd); } -@@ -1766,6 +1787,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1772,6 +1794,7 @@ res = pr_fsio_write(stor_fh, lbuf, len); if (res != len) { int xerrno = EIO; @@ -331,7 +315,7 @@ if (res < 0) xerrno = errno; -@@ -1795,6 +1817,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1801,6 +1824,7 @@ /* default abort errno, in case session.d et al has already gone away */ int xerrno = ECONNABORTED; @@ -339,7 +323,7 @@ stor_abort(); -@@ -1814,6 +1837,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1820,6 +1844,7 @@ if (stor_complete() < 0) { int xerrno = errno; @@ -347,7 +331,7 @@ _log_transfer('i', 'i'); -@@ -1826,12 +1850,14 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1832,12 +1857,14 @@ if (xerrno == EDQUOT) { pr_response_add_err(R_552, "%s: %s", cmd->arg, strerror(xerrno)); errno = xerrno; @@ -362,7 +346,7 @@ return PR_ERROR(cmd); } #endif -@@ -1845,6 +1871,7 @@ MODRET xfer_stor(cmd_rec *cmd) { +@@ -1851,6 +1878,7 @@ session.xfer.path_hidden) { if (pr_fsio_rename(session.xfer.path_hidden, session.xfer.path) != 0) { int xerrno = errno; @@ -370,7 +354,7 @@ /* This should only fail on a race condition with a chmod/chown * or if STOR_APPEND is on and the permissions are squirrely. -@@ -1947,6 +1974,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) { +@@ -1953,6 +1981,7 @@ pr_response_add_err(R_500, _("'%s' not understood"), pr_cmd_get_displayable_str(cmd, NULL)); errno = EINVAL; @@ -378,7 +362,7 @@ return PR_ERROR(cmd); } -@@ -1956,6 +1984,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) { +@@ -1962,6 +1991,7 @@ if (!dir || !dir_check(cmd->tmp_pool, cmd, cmd->group, dir, NULL)) { int xerrno = errno; @@ -386,7 +370,7 @@ pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); -@@ -1978,12 +2007,14 @@ MODRET xfer_pre_retr(cmd_rec *cmd) { +@@ -1984,12 +2014,14 @@ if (xfer_check_limit(cmd) < 0) { pr_response_add_err(R_451, _("%s: Too many transfers"), cmd->arg); errno = EPERM; @@ -401,7 +385,7 @@ pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(xerrno)); -@@ -2000,6 +2031,7 @@ MODRET xfer_pre_retr(cmd_rec *cmd) { +@@ -2006,6 +2038,7 @@ /* Deliberately use EISDIR for anything non-file (e.g. directories). */ errno = EISDIR; @@ -409,7 +393,7 @@ return PR_ERROR(cmd); } -@@ -2014,12 +2046,14 @@ MODRET xfer_pre_retr(cmd_rec *cmd) { +@@ -2020,12 +2053,14 @@ cmd->arg); session.restart_pos = 0L; errno = EPERM; @@ -424,7 +408,7 @@ if (errno != EEXIST) { pr_log_pri(PR_LOG_NOTICE, "notice: error adding 'mod_xfer.retr-path': %s", strerror(errno)); -@@ -2046,6 +2080,7 @@ MODRET xfer_retr(cmd_rec *cmd) { +@@ -2052,6 +2087,7 @@ retr_fh = pr_fsio_open(dir, O_RDONLY); if (retr_fh == NULL) { int xerrno = errno; @@ -432,7 +416,7 @@ (void) pr_trace_msg("fileperms", 1, "%s, user '%s' (UID %lu, GID %lu): " "error opening '%s': %s", cmd->argv[0], session.user, -@@ -2059,6 +2094,7 @@ MODRET xfer_retr(cmd_rec *cmd) { +@@ -2065,6 +2101,7 @@ if (pr_fsio_stat(dir, &st) < 0) { /* Error stat'ing the file. */ int xerrno = errno; @@ -440,7 +424,7 @@ pr_fsio_close(retr_fh); errno = xerrno; -@@ -2083,6 +2119,7 @@ MODRET xfer_retr(cmd_rec *cmd) { +@@ -2089,6 +2126,7 @@ if (pr_fsio_lseek(retr_fh, session.restart_pos, SEEK_SET) == (off_t) -1) { int xerrno = errno; @@ -448,7 +432,7 @@ pr_fsio_close(retr_fh); errno = xerrno; retr_fh = NULL; -@@ -2143,6 +2180,7 @@ MODRET xfer_retr(cmd_rec *cmd) { +@@ -2149,6 +2187,7 @@ retr_abort(); /* Set errno to EPERM ("Operation not permitted") */ @@ -456,7 +440,7 @@ pr_data_abort(EPERM, FALSE); return PR_ERROR(cmd); } -@@ -2174,6 +2212,7 @@ MODRET xfer_retr(cmd_rec *cmd) { +@@ -2180,6 +2219,7 @@ * is preserved; errno itself might be overwritten in retr_abort(). */ int xerrno = errno; @@ -464,3 +448,16 @@ retr_abort(); pr_data_abort(xerrno, FALSE); +--- a/include/dirtree.h 2016-03-10 17:04:32.000000000 -0800 ++++ proftpd-1.3.5b/include/dirtree.h 2016-04-01 02:00:13.315707095 -0700 +@@ -127,6 +127,10 @@ + + int cmd_id; /* Index into commands list, for faster comparisons */ + ++ int error_code; /* Stores errno of failed file transfer commands. ++ * Required for Solaris auditing. ++ */ ++ + /* If we detect that the client sent commands for a protocol OTHER than + * FTP, then this field will be FALSE; the protocol field will identify + * the detected protocol. diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/006.18845170.patch --- a/components/proftpd/patches/006.18845170.patch Wed Apr 27 13:38:51 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -http://bugs.proftpd.org/show_bug.cgi?id=4069 -https://github.com/proftpd/proftpd/commit/38cf9e5028cbddee2b0dcba436d60199da1edf80 - ---- a/modules/mod_ls.c -+++ b/modules/mod_ls.c -@@ -2755,6 +2755,13 @@ MODRET ls_nlst(cmd_rec *cmd) { - parse_list_opts(&list_options, &glob_flags, TRUE); - } - -+ /* If, after parsing out any options, the target string is empty, assume -+ * the current directory (Bug#4069). -+ */ -+ if (*target == '\0') { -+ target = pstrdup(cmd->tmp_pool, "."); -+ } -+ - /* If the target starts with '~' ... */ - if (*target == '~') { - char pb[PR_TUNABLE_PATH_MAX + 1] = {'\0'}; - diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/009.19668629.patch --- a/components/proftpd/patches/009.19668629.patch Wed Apr 27 13:38:51 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -http://bugs.proftpd.org/show_bug.cgi?id=4109 -https://github.com/proftpd/proftpd/commit/0b8afb267eb6fd6acf98595a8c2812cd27ac11a0 - -diff --git a/src/inet.c b/src/inet.c -index f5602e0..d0a0631 100644 ---- a/src/inet.c -+++ b/src/inet.c -@@ -770,8 +770,9 @@ int pr_inet_set_proto_opts(pool *p, conn_t *c, int mss, int nodelay, - if (pr_netaddr_use_ipv6()) { - /* Only set TCLASS flags on IPv6 sockets; IPv4 sockets use TOS. */ - if (pr_netaddr_get_family(c->local_addr) == AF_INET6) { -+ int level = ipv6_proto; - if (c->listen_fd != -1) { -- if (setsockopt(c->listen_fd, ip_level, IPV6_TCLASS, (void *) &tos, -+ if (setsockopt(c->listen_fd, level, IPV6_TCLASS, (void *) &tos, - sizeof(tos)) < 0) { - pr_log_pri(PR_LOG_NOTICE, "error setting listen fd IPV6_TCLASS: %s", - strerror(errno)); diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/013-21514375-4143-tls-xss.patch --- a/components/proftpd/patches/013-21514375-4143-tls-xss.patch Wed Apr 27 13:38:51 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,207 +0,0 @@ -http://bugs.proftpd.org/show_bug.cgi?id=4143#c0 -https://github.com/proftpd/proftpd/pull/81.patch - -diff --git a/include/cmd.h b/include/cmd.h -index a95cac3..814dc62 100644 ---- a/include/cmd.h -+++ b/include/cmd.h -@@ -106,6 +106,16 @@ int pr_cmd_get_id(const char *name_name); - #define PR_CMD_MIN_NAMELEN 3 - #define PR_CMD_MAX_NAMELEN 4 - -+/* Returns TRUE if the given command is a known HTTP method, FALSE if not -+ * a known HTTP method, and -1 if there is an error. -+ */ -+int pr_cmd_is_http(cmd_rec *c); -+ -+/* Returns TRUE if the given command is a known SMTP method, FALSE if not -+ * a known SMTP method, and -1 if there is an error. -+ */ -+int pr_cmd_is_smtp(cmd_rec *c); -+ - int pr_cmd_set_name(cmd_rec *, const char *); - - /* Implemented in main.c */ -diff --git a/include/dirtree.h b/include/dirtree.h -index fe7b14b..ddb31a8 100644 ---- a/include/dirtree.h -+++ b/include/dirtree.h -@@ -130,6 +130,13 @@ typedef struct cmd_struc { - int error_code; /* Stores errno of failed file transfer - * commands. Required for Solaris auditing. - */ -+ -+ /* If we detect that the client sent commands for a protocol OTHER than -+ * FTP, then this field will be FALSE; the protocol field will identify -+ * the detected protocol. -+ */ -+ int is_ftp; -+ const char *protocol; - } cmd_rec; - - struct config_struc { -diff --git a/include/session.h b/include/session.h -index a0ccd1a..d47ea83 100644 ---- a/include/session.h -+++ b/include/session.h -@@ -72,6 +72,9 @@ - /* Disconnected due to snprintf(3) buffer truncation. */ - #define PR_SESS_DISCONNECT_SNPRINTF_TRUNCATED 13 - -+/* Disconnected due to wrong protocol used (e.g. HTTP/SMTP). */ -+#define PR_SESS_DISCONNECT_BAD_PROTOCOL 14 -+ - /* Returns a string describing the reason the client was disconnected or - * the session ended. If a pointer to a char * was provided, any extra - * disconnect details will be provided. -diff --git a/src/cmd.c b/src/cmd.c -index b441c54..4688ff3 100644 ---- a/src/cmd.c -+++ b/src/cmd.c -@@ -112,6 +112,38 @@ static struct cmd_entry cmd_ids[] = { - { NULL, 0 } - }; - -+/* Due to potential XSS issues (see Bug#4143), we want to explicitly -+ * check for commands from other text-based protocols (e.g. HTTP and SMTP); -+ * if we see these, we want to close the connection with extreme prejudice. -+ */ -+ -+static struct cmd_entry http_ids[] = { -+ { " ", 1 }, /* Index 0 is intentionally filled with a sentinel */ -+ { "CONNECT", 7 }, -+ { "DELETE", 6 }, -+ { "GET", 3 }, -+ { "HEAD", 4 }, -+ { "OPTIONS", 7 }, -+ { "PATCH", 5 }, -+ { "POST", 4 }, -+ { "PUT", 3 }, -+ -+ { NULL, 0 } -+}; -+ -+static struct cmd_entry smtp_ids[] = { -+ { " ", 1 }, /* Index 0 is intentionally filled with a sentinel */ -+ { "DATA", 4 }, -+ { "EHLO", 4 }, -+ { "HELO", 4 }, -+ { "MAIL", 4 }, -+ { "RCPT", 4 }, -+ { "RSET", 4 }, -+ { "VRFY", 4 }, -+ -+ { NULL, 0 } -+}; -+ - cmd_rec *pr_cmd_alloc(pool *p, int argc, ...) { - pool *newpool = NULL; - cmd_rec *cmd = NULL; -@@ -340,3 +372,59 @@ int pr_cmd_get_id(const char *cmd_name) { - errno = ENOENT; - return -1; - } -+ -+static int is_known_cmd(struct cmd_entry *known_cmds, const char *cmd_name, -+ size_t cmd_namelen) { -+ register unsigned int i; -+ int known = FALSE; -+ -+ for (i = 0; known_cmds[i].cmd_name != NULL; i++) { -+ if (cmd_namelen == known_cmds[i].cmd_namelen) { -+ if (strncmp(cmd_name, known_cmds[i].cmd_name, cmd_namelen + 1) == 0) { -+ known = TRUE; -+ break; -+ } -+ } -+ } -+ -+ return known; -+} -+ -+int pr_cmd_is_http(cmd_rec *cmd) { -+ const char *cmd_name; -+ size_t cmd_namelen; -+ -+ if (cmd == NULL) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ cmd_name = cmd->argv[0]; -+ if (cmd_name == NULL) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ cmd_namelen = strlen(cmd_name); -+ return is_known_cmd(http_ids, cmd_name, cmd_namelen); -+} -+ -+int pr_cmd_is_smtp(cmd_rec *cmd) { -+ const char *cmd_name; -+ size_t cmd_namelen; -+ -+ if (cmd == NULL) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ cmd_name = cmd->argv[0]; -+ if (cmd_name == NULL) { -+ errno = EINVAL; -+ return -1; -+ } -+ -+ cmd_namelen = strlen(cmd_name); -+ return is_known_cmd(smtp_ids, cmd_name, cmd_namelen); -+} -+ -diff --git a/src/main.c b/src/main.c -index b951436..b0a8a2a 100644 ---- a/src/main.c -+++ b/src/main.c -@@ -572,7 +572,21 @@ int pr_cmd_read(cmd_rec **res) { - cmd = make_ftp_cmd(session.pool, cp, flags); - if (cmd) { - *res = cmd; -- } -+ -+ if (pr_cmd_is_http(cmd) == TRUE) { -+ cmd->is_ftp = FALSE; -+ cmd->protocol = "HTTP"; -+ -+ } else if (pr_cmd_is_smtp(cmd) == TRUE) { -+ cmd->is_ftp = FALSE; -+ cmd->protocol = "SMTP"; -+ -+ } else { -+ /* Assume that the client is sending valid FTP commands. */ -+ cmd->is_ftp = TRUE; -+ cmd->protocol = "FTP"; -+ } -+ } - } - - return 0; -@@ -827,6 +841,20 @@ static void cmd_loop(server_rec *server, conn_t *c) { - } - - if (cmd) { -+ -+ /* Detect known commands for other protocols; if found, drop the -+ * connection, lest we be used as part of an attack on a different -+ * protocol server (Bug#4143). -+ */ -+ if (cmd->is_ftp == FALSE) { -+ pr_log_pri(PR_LOG_WARNING, -+ "client sent %s command '%s', disconnecting", cmd->protocol, -+ cmd->argv[0]); -+ pr_event_generate("core.bad-protocol", cmd); -+ pr_session_disconnect(NULL, PR_SESS_DISCONNECT_BAD_PROTOCOL, -+ cmd->protocol); -+ } -+ - pr_cmd_dispatch(cmd); - destroy_pool(cmd->pool); - diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/patches/014-21696066-4124.patch --- a/components/proftpd/patches/014-21696066-4124.patch Wed Apr 27 13:38:51 2016 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -http://bugs.proftpd.org/show_bug.cgi?id=4124 -https://patch-diff.githubusercontent.com/raw/proftpd/proftpd/pull/60.patch - -diff --git a/modules/mod_xfer.c b/modules/mod_xfer.c -index ddd4f34..339f89a 100644 ---- a/modules/mod_xfer.c -+++ b/modules/mod_xfer.c -@@ -974,7 +974,7 @@ static void stor_abort(void) { - - } else if (session.xfer.path) { - delete_stores = get_param_ptr(CURRENT_CONF, "DeleteAbortedStores", FALSE); -- if (delete_stores == NULL || -+ if (delete_stores != NULL && - *delete_stores == TRUE) { - pr_log_debug(DEBUG5, "removing aborted file '%s'", session.xfer.path); - pr_fsio_unlink(session.xfer.path); diff -r 986a46fa92f7 -r 0f3d50fefade components/proftpd/proftpd.p5m --- a/components/proftpd/proftpd.p5m Wed Apr 27 13:38:51 2016 -0700 +++ b/components/proftpd/proftpd.p5m Tue Apr 26 00:28:11 2016 -0700 @@ -18,7 +18,7 @@ # # CDDL HEADER END # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. # # PSARC/2011/088 @@ -35,21 +35,33 @@ set name=info.upstream-url value=$(COMPONENT_PROJECT_URL) set name=org.opensolaris.arc-caseid value=PSARC/2011/088 set name=org.opensolaris.consolidation value=$(CONSOLIDATION) - - +# +# config. file file proftpd.conf path=etc/proftpd.conf mode=0644 overlay=allow preserve=true +# +# SMF(5) file auth_service-network-ftpd \ path=etc/security/auth_attr.d/service-network-ftpd file prof_service-network-ftpd \ path=etc/security/prof_attr.d/service-network-ftpd file ftp.xml path=lib/svc/manifest/network/ftp.xml file svc-ftp path=lib/svc/method/svc-ftp +# +# executables +file path=usr/bin/ftpasswd file path=usr/bin/ftpcount file path=usr/bin/ftpdctl +file path=usr/bin/ftpmail +file path=usr/bin/ftpquota file path=usr/bin/ftptop file path=usr/bin/ftpwho file path=usr/bin/prxs +# +# dtrace demo file dtrace/example.d path=usr/demo/dtrace/ftp.d +# +# headers +file path=usr/include/proftpd/ascii.h file path=usr/include/proftpd/auth.h file path=usr/include/proftpd/bindings.h file path=usr/include/proftpd/buildstamp.h @@ -74,12 +86,16 @@ file path=usr/include/proftpd/ftp.h file path=usr/include/proftpd/glibc-glob.h file path=usr/include/proftpd/help.h +file path=usr/include/proftpd/ident.h file path=usr/include/proftpd/inet.h +file path=usr/include/proftpd/lastlog.h file path=usr/include/proftpd/libsupp.h file path=usr/include/proftpd/log.h +file path=usr/include/proftpd/memcache.h file path=usr/include/proftpd/mkhome.h file path=usr/include/proftpd/mod_ctrls.h file path=usr/include/proftpd/mod_gss.h +file path=usr/include/proftpd/mod_log.h file path=usr/include/proftpd/mod_tls.h file path=usr/include/proftpd/modules.h file path=usr/include/proftpd/netacl.h @@ -95,29 +111,45 @@ file path=usr/include/proftpd/proftpd.h file path=usr/include/proftpd/regexp.h file path=usr/include/proftpd/response.h +file path=usr/include/proftpd/rlimit.h file path=usr/include/proftpd/scoreboard.h file path=usr/include/proftpd/session.h file path=usr/include/proftpd/sets.h +file path=usr/include/proftpd/stash.h file path=usr/include/proftpd/str.h file path=usr/include/proftpd/support.h file path=usr/include/proftpd/table.h file path=usr/include/proftpd/throttle.h file path=usr/include/proftpd/timers.h +file path=usr/include/proftpd/tpl.h file path=usr/include/proftpd/trace.h +file path=usr/include/proftpd/utf8.h file path=usr/include/proftpd/var.h file path=usr/include/proftpd/version.h file path=usr/include/proftpd/xferlog.h +# +# dtrace file dtrace/ftp.d path=usr/lib/dtrace/ftp.d +# +# servicing daemon file usr/sbin/proftpd path=usr/lib/inet/proftpd +# +# pkg-config file path=usr/lib/pkgconfig/proftpd.pc +# +# modules file path=usr/lib/proftpd/mod_auth_gss.so file path=usr/lib/proftpd/mod_facl.so file path=usr/lib/proftpd/mod_gss.so file path=usr/lib/proftpd/mod_tls.so file path=usr/lib/proftpd/mod_wrap.so +# +# sbin executables file ftprestart.sh path=usr/sbin/ftprestart file path=usr/sbin/ftpscrub file path=usr/sbin/ftpshut +# +# documentation file doc/Configuration.html path=usr/share/doc/proftpd/Configuration.html file doc/modules/mod_auth_file.html \ path=usr/share/doc/proftpd/modules/mod_auth_file.html @@ -138,8 +170,11 @@ file doc/contrib/mod_tls.html path=usr/share/doc/proftpd/modules/mod_tls.html file doc/contrib/mod_wrap.html path=usr/share/doc/proftpd/modules/mod_wrap.html file proftpd_migration.txt path=usr/share/doc/proftpd/proftpd_migration.txt +# +# .mo files file path=usr/share/locale/bg_BG/LC_MESSAGES/proftpd.mo file path=usr/share/locale/en_US/LC_MESSAGES/proftpd.mo +file path=usr/share/locale/es_ES/LC_MESSAGES/proftpd.mo file usr/share/locale/fr_FR/LC_MESSAGES/proftpd.mo \ path=usr/share/locale/fr/LC_MESSAGES/proftpd.mo file usr/share/locale/it_IT/LC_MESSAGES/proftpd.mo \ @@ -152,7 +187,12 @@ path=usr/share/locale/ru/LC_MESSAGES/proftpd.mo file path=usr/share/locale/zh_CN/LC_MESSAGES/proftpd.mo file path=usr/share/locale/zh_TW/LC_MESSAGES/proftpd.mo +# +# man pages +file path=usr/share/man/man1/ftpasswd.1 file path=usr/share/man/man1/ftpcount.1 +file path=usr/share/man/man1/ftpmail.1 +file path=usr/share/man/man1/ftpquota.1 file path=usr/share/man/man1/ftptop.1 file path=usr/share/man/man1/ftpwho.1 file path=usr/share/man/man5/proftpd.conf.5 @@ -161,8 +201,12 @@ file path=usr/share/man/man8/ftpscrub.8 file path=usr/share/man/man8/ftpshut.8 file path=usr/share/man/man8/proftpd.8 +# +# user/group (added by pkg) group groupname=ftp gid=21 user username=ftp ftpuser=false gcos-field="FTPD Reserved UID" group=ftp uid=21 +# +# pkg meta legacy pkg=SUNWftpu desc="FTP Server and Utilities" name="FTP Server, (Usr)" license proftpd.license license="GPLv2 (mod_gss)" \ com.oracle.info.description="the ProFPTD GSS Engine" \