[Git][debian-proftpd-team/proftpd][upstream] New upstream version 1.3.8.c+dfsg
Hilmar Preuße (@hilmar)
gitlab at salsa.debian.org
Fri Dec 13 22:07:00 GMT 2024
Hilmar Preuße pushed to branch upstream at Debian ProFTPD Team / proftpd
Commits:
91f64bbe by Hilmar Preuße at 2024-12-12T23:29:48+01:00
New upstream version 1.3.8.c+dfsg
- - - - -
24 changed files:
- .cirrus.yml
- .github/workflows/ci.yml
- .github/workflows/rpm.yml
- NEWS
- RELEASE_NOTES
- configure
- configure.in
- contrib/dist/rpm/proftpd.spec
- contrib/mod_radius.c
- contrib/mod_sftp/auth.c
- contrib/mod_sftp/fxp.c
- contrib/mod_sftp/keys.c
- contrib/mod_sftp/mod_sftp.h.in
- contrib/mod_sftp_sql.c
- contrib/mod_tls.c
- include/version.h
- modules/mod_auth.c
- src/auth.c
- src/event.c
- src/fsio.c
- tests/api/inet.c
- tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm
- tests/t/lib/ProFTPD/Tests/Modules/mod_sftp_sql.pm
- tests/t/lib/ProFTPD/Tests/Modules/mod_sql_sqlite.pm
Changes:
=====================================
.cirrus.yml
=====================================
@@ -3,8 +3,7 @@ task:
name: build
freebsd_instance:
matrix:
- image_family: freebsd-13-2
- image_family: freebsd-12-4
+ image_family: freebsd-14-0
env:
CIRRUS_CLONE_DEPTH: 10
@@ -20,12 +19,12 @@ task:
- pkg install -y libsodium
- pkg install -y libmaxminddb
- pkg install -y libmemcached
- - pkg install -y mysql57-client
+ - pkg install -y mysql80-client
- pkg install -y ncurses
- pkg install -y openldap26-client
- pkg install -y openssl
- pkg install -y pcre
- - pkg install -y postgresql11-client
+ - pkg install -y postgresql13-client
- pkg install -y sqlite3
- pkg install -y unixODBC
# For the Redis unit tests
=====================================
.github/workflows/ci.yml
=====================================
@@ -7,6 +7,7 @@ on:
paths-ignore:
- NEWS
- RELEASE_NOTES
+ - 'doc/**'
- '**/*.html'
- '**/*.md'
pull_request:
@@ -15,6 +16,7 @@ on:
paths-ignore:
- NEWS
- RELEASE_NOTES
+ - 'doc/**'
- '**/*.html'
- '**/*.md'
@@ -36,7 +38,12 @@ jobs:
environment: CI
env:
- PACKAGE_VERSION: 1.3.8rc5
+ # We need to avoid using NodeJS v20, because it doesn't work with
+ # older glibc versions. See:
+ # https://github.com/actions/checkout/issues/1809.
+ ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
+
+ PACKAGE_VERSION: 1.3.8c
REDIS_HOST: redis
strategy:
@@ -46,8 +53,8 @@ jobs:
- gcc
container:
- almalinux:8
- - alpine:3.14
- - ubuntu:18.04
+ - alpine:3.18
+ - ubuntu:22.04
container: ${{ matrix.container }}
@@ -56,7 +63,7 @@ jobs:
uses: actions/checkout at v2
- name: Whitespace check
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
apt-get update -qq
apt-get install -y git
@@ -68,11 +75,11 @@ jobs:
fi
- name: Install Alpine packages
- if: ${{ matrix.container == 'alpine:3.14' }}
+ if: ${{ matrix.container == 'alpine:3.18' }}
run: |
apk update
# for builds
- apk add bash build-base clang compiler-rt-static gcc make zlib-dev
+ apk add bash build-base clang compiler-rt gcc make zlib-dev
# for unit tests
apk add check check-dev subunit subunit-dev
@@ -161,8 +168,6 @@ jobs:
yum install -y libsodium-devel
# for mod_sql_sqlite
yum install -y sqlite-devel
- # for mod_wrap
- yum install -y libnsl2-devel https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/tcp_wrappers-libs-7.6-77.el7.x86_64.rpm https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/tcp_wrappers-devel-7.6-77.el7.x86_64.rpm
# for PCRE2 support
yum install -y pcre2-devel
# for ftptop
@@ -179,7 +184,7 @@ jobs:
yum install -y clang
# The modules to build are distro-specific
- echo "PROFTPD_MODULES=mod_sql:mod_sql_mysql:mod_sql_odbc:mod_sql_postgres:mod_sql_sqlite:mod_sql_passwd:mod_sftp:mod_sftp_sql:mod_sftp_pam:mod_tls:mod_tls_fscache:mod_tls_shmcache:mod_tls_memcache:mod_tls_redis:mod_ban:mod_copy:mod_ctrls_admin:mod_deflate:mod_dnsbl:mod_dynmasq:mod_exec:mod_facl:mod_geoip:mod_ifversion:mod_ldap:mod_load:mod_log_forensic:mod_qos:mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql:mod_radius:mod_readme:mod_rewrite:mod_shaper:mod_site_misc:mod_snmp:mod_wrap:mod_wrap2:mod_wrap2_file:mod_wrap2_redis:mod_wrap2_sql:mod_digest:mod_auth_otp:mod_statcache:mod_unique_id:mod_ifsession" >> $GITHUB_ENV
+ echo "PROFTPD_MODULES=mod_sql:mod_sql_mysql:mod_sql_odbc:mod_sql_postgres:mod_sql_sqlite:mod_sql_passwd:mod_sftp:mod_sftp_sql:mod_sftp_pam:mod_tls:mod_tls_fscache:mod_tls_shmcache:mod_tls_memcache:mod_tls_redis:mod_ban:mod_copy:mod_ctrls_admin:mod_deflate:mod_dnsbl:mod_dynmasq:mod_exec:mod_facl:mod_geoip:mod_ifversion:mod_ldap:mod_load:mod_log_forensic:mod_qos:mod_quotatab:mod_quotatab_file:mod_quotatab_ldap:mod_quotatab_radius:mod_quotatab_sql:mod_radius:mod_readme:mod_rewrite:mod_shaper:mod_site_misc:mod_snmp:mod_wrap2:mod_wrap2_file:mod_wrap2_redis:mod_wrap2_sql:mod_digest:mod_auth_otp:mod_statcache:mod_unique_id:mod_ifsession" >> $GITHUB_ENV
# for debugging
clang --version
@@ -187,7 +192,7 @@ jobs:
openssl version -a
- name: Install Ubuntu packages
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
# Need to add other repos for e.g. libsodium
apt-get update -qq
@@ -230,7 +235,7 @@ jobs:
# for mod_wrap
apt-get install -y libwrap0-dev
# for PCRE2 support
- apt-get install -y libpcre2-dev libpcre2-posix0
+ apt-get install -y libpcre2-dev libpcre2-posix3
# for ftptop
apt-get install -y ncurses-dev
# for zlib support
@@ -238,7 +243,6 @@ jobs:
# for logging
apt-get install -y rsyslog
- service rsyslog start
# for static code analysis
# - sudo apt-get install -y cppcheck
@@ -261,7 +265,7 @@ jobs:
openssl version -a
- name: Prepare code coverage
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
lcov --directory . --zerocounters
@@ -280,14 +284,14 @@ jobs:
# On recent (as of 2022-11-13) AlmaLinux with clang and the
# `--enable-devel=fortify` configure settings, some of the unit tests
# inexplicably fail. So skip clang unit tests, for now.
- if: ${{ matrix.compiler == 'gcc' && matrix.container != 'alpine:3.14' }}
+ if: ${{ matrix.compiler == 'gcc' && matrix.container != 'alpine:3.18' }}
run: |
make TEST_VERBOSE=1 check-api
- name: Upload code coverage
env:
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- if: ${{ matrix.compiler == 'gcc' && matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.compiler == 'gcc' && matrix.container == 'ubuntu:22.04' }}
run: |
lcov --ignore-errors gcov,source --directory . --capture --output-file all.info
# filter out system and test code
@@ -313,7 +317,7 @@ jobs:
PROFTPD_TEST_PIDFILE: /usr/local/var/proftpd.pid
# Note that the default config assumes user 'nobody', group 'nogroup',
# which do not exist in the default images of all distributions.
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
test -e $PROFTPD_TEST_BIN
$PROFTPD_TEST_BIN
@@ -358,7 +362,7 @@ jobs:
CC: ${{ matrix.compiler }}
CFLAGS: -fsanitize=address,undefined -DPR_DEVEL_NO_POOL_FREELIST
LDFLAGS: -fsanitize=address,undefined
- if: ${{ matrix.compiler == 'clang' && matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.compiler == 'clang' && matrix.container == 'ubuntu:22.04' }}
run: |
make clean
./configure LIBS="-lm -lsubunit -lrt -pthread" --enable-devel --enable-ctrls --enable-facl --enable-memcache --enable-nls --enable-pcre2 --enable-redis --enable-tests
@@ -367,12 +371,12 @@ jobs:
make check-api
- name: Check Perl scripts
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
perl -cw contrib/ftpasswd
perl -cw contrib/ftpquota
- name: Check HTML docs
- if: ${{ matrix.container == 'ubuntu:18.04' }}
+ if: ${{ matrix.container == 'ubuntu:22.04' }}
run: |
for f in $(/bin/ls doc/contrib/*.html doc/directives/*.html doc/howto/*.html doc/modules/*.html doc/utils/*.html); do echo "Processing $f"; tidy -errors -omit -q $f; done || exit 0
=====================================
.github/workflows/rpm.yml
=====================================
@@ -7,6 +7,7 @@ on:
paths-ignore:
- NEWS
- RELEASE_NOTES
+ - 'doc/**'
- '**/*.html'
- '**/*.md'
pull_request:
@@ -15,6 +16,7 @@ on:
paths-ignore:
- NEWS
- RELEASE_NOTES
+ - 'doc/**'
- '**/*.html'
- '**/*.md'
@@ -22,6 +24,12 @@ jobs:
build:
runs-on: ubuntu-latest
+ env:
+ # We need to avoid using NodeJS v20, because it doesn't work with
+ # older glibc versions. See:
+ # https://github.com/actions/checkout/issues/1809.
+ ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
+
strategy:
matrix:
container:
@@ -40,8 +48,6 @@ jobs:
yum install -y dnf-plugins-core epel-release yum-utils
dnf config-manager --enable epel
dnf config-manager --set-enabled powertools
- # for mod_wrap
- yum install -y libnsl2-devel https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/tcp_wrappers-libs-7.6-77.el7.x86_64.rpm https://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/tcp_wrappers-devel-7.6-77.el7.x86_64.rpm
- name: Install packages
run: |
=====================================
NEWS
=====================================
@@ -15,6 +15,20 @@
where `N' is the issue number.
-----------------------------------------------------------------------------
+1.3.8c - Released 11-Dec-2024
+--------------------------------
+- Issue 1770 - Using FTPS after upgrading from 1.3.8a to 1.3.8b leads to crash.
+- Issue 1785 - Bad handling of lack of extended attributes leads to SFTP out of
+ memory error.
+- Issue 1529 - mod_sftp_sql logs "header value too long" due to unexpected key
+ header text.
+- Issue 1839 - SSH ECDSA host key algorithms not be used as expected despite
+ configuring appropriate key.
+- Issue 1840 - RADIUS Message-Authenticator verification failed with ProFTPD
+ mod_radius.
+- Issue 1830 - Supplemental group inheritance grants unintended access to
+ GID 0 due to lack of supplemental groups from mod_sql.
+
1.3.8b - Released 19-Dec-2023
--------------------------------
- Issue 1735 - Compiling ProFTPD 1.3.8a mod_sftp, mod_tls using libressl 3.7.3
=====================================
RELEASE_NOTES
=====================================
@@ -6,6 +6,19 @@ This file contains a description of the major changes to ProFTPD for the
releases. More information on these changes can be found in the NEWS and
ChangeLog files.
+1.3.8c
+------
+
+ + Fixed segfault when TLSOptions StdEnvVars is used in conjunction with
+ an FTPS session.
+
+ + Properly use all configured ECDSA SSH hostkeys, not just the first
+ configured ECSA SSH hostkey.
+
+ + Fixed issue with RADIUS authentication when using mod_radius and newer
+ FreeRADIUS, due to BlastRadius mitigation.
+
+
1.3.8b
------
=====================================
configure
=====================================
@@ -21419,7 +21419,7 @@ main ()
{
size_t res, in_len = 0, out_len = 0;
- const char *in = NULL;
+ char *in = NULL;
char *out = NULL;
res = iconv((iconv_t)-1, &in, &in_len, &out, &out_len);
=====================================
configure.in
=====================================
@@ -2044,7 +2044,7 @@ AC_TRY_LINK(
],
[
size_t res, in_len = 0, out_len = 0;
- const char *in = NULL;
+ char *in = NULL;
char *out = NULL;
res = iconv((iconv_t)-1, &in, &in_len, &out, &out_len);
],
=====================================
contrib/dist/rpm/proftpd.spec
=====================================
@@ -53,7 +53,7 @@
# RHEL5 and clones don't have suitably recent versions of pcre/libmemcached
# so use --with rhel5 to inhibit those features when using --with everything
-%global proftpd_version 1.3.8b
+%global proftpd_version 1.3.8c
# rc_version should be incremented for each RC release, and reset back to 1
# AFTER each stable release.
@@ -61,7 +61,7 @@
# release_version should be incremented for each maint release, and reset back
# to 1 BEFORE starting new release cycle.
-%global release_version 3
+%global release_version 4
%if %(echo %{proftpd_version} | grep rc >/dev/null 2>&1 && echo 1 || echo 0)
%global rpm_version %(echo %{proftpd_version} | sed -e 's/rc.*//')
@@ -84,7 +84,7 @@
# Handle optional functionality
#
-# --with everything (for all optional functionality)
+# --with everything (for all optional functionality EXCEPT mod_wrap)
# --with rhel5 inhibits features not available on RHEL5 and clones
# --with rhel6 inhibits features not available on RHEL6 and clones
%if 0%{?_with_everything:1}
@@ -102,8 +102,12 @@
%global _with_postgresql 1
%global _with_ssl 1
%global _with_sodium 1
+#
+# --with wrap (for mod_wrap)
+%if 0%{?_with_wrap:1}
%global _with_wrap 1
%endif
+%endif
#
# --with geoip (for mod_geoip)
%if 0%{?_with_geoip:1}
=====================================
contrib/mod_radius.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD: mod_radius -- a module for RADIUS authentication and accounting
- * Copyright (c) 2001-2022 TJ Saunders
+ * Copyright (c) 2001-2024 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -2266,8 +2266,11 @@ static int radius_verify_auth_mac(radius_packet_t *pkt, const char *pkt_type,
memset(replied, '\0', sizeof(replied));
memcpy(replied, attrib->data, attrib_len);
- /* Next, zero out the value so that we can calculate it ourselves. */
- memset(attrib->data, '\0', attrib_len);
+ /* Next, zero out the value so that we can calculate it ourselves.
+ *
+ * Note that we only want to zero out the first 16 bytes, per RFC 2869.
+ */
+ memset(attrib->data, '\0', expected_len);
memset(digest, '\0', sizeof(digest));
md = EVP_md5();
=====================================
contrib/mod_sftp/auth.c
=====================================
@@ -388,8 +388,20 @@ static int setup_env(pool *p, const char *user) {
session.groups == NULL) {
res = pr_auth_getgroups(p, pw->pw_name, &session.gids, &session.groups);
if (res < 1) {
+ /* If no supplemental groups are provided, default to using the process
+ * primary GID as the supplemental group. This prevents access
+ * regressions as seen in Issue #1830.
+ */
(void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
- "no supplemental groups found for user '%s'", pw->pw_name);
+ "no supplemental groups found for user '%s', "
+ "using primary group %s (GID %lu)", pw->pw_name, session.group,
+ (unsigned long) session.login_gid);
+
+ session.gids = make_array(p, 2, sizeof(gid_t));
+ session.groups = make_array(p, 2, sizeof(char *));
+
+ *((gid_t *) push_array(session.gids)) = session.login_gid;
+ *((char **) push_array(session.groups)) = pstrdup(p, session.group);
}
}
=====================================
contrib/mod_sftp/fxp.c
=====================================
@@ -2593,6 +2593,7 @@ static uint32_t fxp_xattrs_write(pool *p, struct fxp_buffer *fxb,
if (valsz > 0) {
*((pr_buffer_t **) push_array(vals)) = val;
}
+
} else {
/* Push the empty buffer into the list, so that the vals list
* lines up with the names list.
=====================================
contrib/mod_sftp/keys.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_sftp key mgmt (keys)
- * Copyright (c) 2008-2023 TJ Saunders
+ * Copyright (c) 2008-2024 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -4143,8 +4143,9 @@ int sftp_keys_have_ecdsa_hostkey(pool *p, int **nids) {
}
count++;
EC_KEY_free(ec);
+ }
- } else if (sftp_ecdsa384_hostkey != NULL) {
+ if (sftp_ecdsa384_hostkey != NULL) {
EC_KEY *ec;
ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa384_hostkey->pkey);
@@ -4153,8 +4154,9 @@ int sftp_keys_have_ecdsa_hostkey(pool *p, int **nids) {
}
count++;
EC_KEY_free(ec);
+ }
- } else if (sftp_ecdsa521_hostkey != NULL) {
+ if (sftp_ecdsa521_hostkey != NULL) {
EC_KEY *ec;
ec = EVP_PKEY_get1_EC_KEY(sftp_ecdsa521_hostkey->pkey);
=====================================
contrib/mod_sftp/mod_sftp.h.in
=====================================
@@ -101,7 +101,9 @@
#include <openssl/rsa.h>
#if OPENSSL_VERSION_NUMBER > 0x000907000L
# include <openssl/aes.h>
-# include <openssl/engine.h>
+# ifdef PR_USE_OPENSSL_ENGINE
+# include <openssl/engine.h>
+# endif /* PR_USE_OPENSSL_ENGINE */
# include <openssl/ocsp.h>
#endif
#if defined(PR_USE_OPENSSL_ECC)
=====================================
contrib/mod_sftp_sql.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD: mod_sftp_sql -- SQL backend module for retrieving authorized keys
- * Copyright (c) 2008-2022 TJ Saunders
+ * Copyright (c) 2008-2024 TJ Saunders
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -93,7 +93,8 @@ static char *sqlstore_getline(pool *p, char **blob, size_t *bloblen) {
return NULL;
}
- while (data != NULL && datalen > 0) {
+ while (data != NULL &&
+ datalen > 0) {
char *ptr;
size_t delimlen, linelen;
int have_line_continuation = FALSE;
@@ -187,13 +188,28 @@ static char *sqlstore_getline(pool *p, char **blob, size_t *bloblen) {
}
/* Header value starts at 2 after the ':' (one for the mandatory
- * space character.
+ * space character. Make sure to check that we actually have text
+ * after the ':' character (see Issue #1529).
*/
- header_valuelen = linelen - (header_taglen + 2);
- if (header_valuelen > 1024) {
+ if (header_taglen + 2 < linelen) {
+ header_valuelen = linelen - (header_taglen + 2);
+ if (header_valuelen > 1024) {
+ (void) pr_log_writefile(sftp_logfd, MOD_SFTP_SQL_VERSION,
+ "header value too long (%u) in retrieved SQL data for '%s'",
+ header_valuelen, sqlstore_user);
+ errno = EINVAL;
+ return NULL;
+ }
+
+ } else {
(void) pr_log_writefile(sftp_logfd, MOD_SFTP_SQL_VERSION,
- "header value too long (%u) in retrieved SQL data for '%s'",
- header_valuelen, sqlstore_user);
+ "empty/missing '%.*s' header value, ignoring", (int) header_taglen,
+ line);
+
+ /* Make sure we advance past this line. */
+ *blob = data;
+ *bloblen = datalen;
+
errno = EINVAL;
return NULL;
}
=====================================
contrib/mod_tls.c
=====================================
@@ -69,7 +69,9 @@
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER > 0x000907000L
-# include <openssl/engine.h>
+# ifdef PR_USE_OPENSSL_ENGINE
+# include <openssl/engine.h>
+# endif /* PR_USE_OPENSSL_ENGINE */
# ifdef PR_USE_OPENSSL_OCSP
# include <openssl/ocsp.h>
# endif /* PR_USE_OPENSSL_OCSP */
@@ -10054,6 +10056,7 @@ static void tls_setup_cert_environ(pool *p, const char *env_prefix,
bio = BIO_new(BIO_s_mem());
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(HAVE_LIBRESSL)) || \
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER >= 0x3050000L)
+ pubkey = X509_get_X509_PUBKEY(cert);
X509_PUBKEY_get0_param(NULL, NULL, NULL, (X509_ALGOR **) &algo, pubkey);
#else
pubkey = cert->cert_info->key;
=====================================
include/version.h
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD - FTP server daemon
- * Copyright (c) 2020-2023 The ProFTPD Project team
+ * Copyright (c) 2020-2024 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,8 +28,8 @@
#include "buildstamp.h"
/* Application version (in various forms) */
-#define PROFTPD_VERSION_NUMBER 0x0001030807
-#define PROFTPD_VERSION_TEXT "1.3.8b"
+#define PROFTPD_VERSION_NUMBER 0x0001030808
+#define PROFTPD_VERSION_TEXT "1.3.8c"
/* Module API version */
#define PR_MODULE_API_VERSION 0x20
=====================================
modules/mod_auth.c
=====================================
@@ -2,7 +2,7 @@
* ProFTPD - FTP server daemon
* Copyright (c) 1997, 1998 Public Flood Software
* Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver at tos.net>
- * Copyright (c) 2001-2022 The ProFTPD Project team
+ * Copyright (c) 2001-2024 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1113,8 +1113,8 @@ static int setup_env(pool *p, cmd_rec *cmd, const char *user, char *pass) {
session.groups = NULL;
}
- if (!session.gids &&
- !session.groups) {
+ if (session.gids == NULL &&
+ session.groups == NULL) {
/* Get the supplemental groups. Note that we only look up the
* supplemental group credentials if we have not cached the group
* credentials before, in session.gids and session.groups.
@@ -1124,8 +1124,19 @@ static int setup_env(pool *p, cmd_rec *cmd, const char *user, char *pass) {
*/
res = pr_auth_getgroups(p, pw->pw_name, &session.gids, &session.groups);
if (res < 1) {
- pr_log_debug(DEBUG5, "no supplemental groups found for user '%s'",
- pw->pw_name);
+ /* If no supplemental groups are provided, default to using the process
+ * primary GID as the supplemental group. This prevents access
+ * regressions as seen in Issue #1830.
+ */
+ pr_log_debug(DEBUG5, "no supplemental groups found for user '%s', "
+ "using primary group %s (GID %lu)", pw->pw_name, session.group,
+ (unsigned long) session.login_gid);
+
+ session.gids = make_array(p, 2, sizeof(gid_t));
+ session.groups = make_array(p, 2, sizeof(char *));
+
+ *((gid_t *) push_array(session.gids)) = session.login_gid;
+ *((char **) push_array(session.groups)) = pstrdup(p, session.group);
}
}
=====================================
src/auth.c
=====================================
@@ -2,7 +2,7 @@
* ProFTPD - FTP server daemon
* Copyright (c) 1997, 1998 Public Flood Software
* Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver at tos.net>
- * Copyright (c) 2001-2022 The ProFTPD Project team
+ * Copyright (c) 2001-2024 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1471,12 +1471,12 @@ int pr_auth_getgroups(pool *p, const char *name, array_header **group_ids,
}
/* Allocate memory for the array_headers of GIDs and group names. */
- if (group_ids) {
- *group_ids = make_array(permanent_pool, 2, sizeof(gid_t));
+ if (group_ids != NULL) {
+ *group_ids = make_array(p, 2, sizeof(gid_t));
}
- if (group_names) {
- *group_names = make_array(permanent_pool, 2, sizeof(char *));
+ if (group_names != NULL) {
+ *group_names = make_array(p, 2, sizeof(char *));
}
cmd = make_cmd(p, 3, name, group_ids ? *group_ids : NULL,
@@ -1495,7 +1495,7 @@ int pr_auth_getgroups(pool *p, const char *name, array_header **group_ids,
* for the benefit of auth_getgroup() implementors.
*/
- if (group_ids) {
+ if (group_ids != NULL) {
register unsigned int i;
char *strgids = "";
gid_t *gids = (*group_ids)->elts;
@@ -1511,7 +1511,7 @@ int pr_auth_getgroups(pool *p, const char *name, array_header **group_ids,
*strgids ? strgids : "(None; corrupted group file?)");
}
- if (group_names) {
+ if (group_names != NULL) {
register unsigned int i;
char *strgroups = "";
char **groups = (*group_names)->elts;
@@ -1527,7 +1527,7 @@ int pr_auth_getgroups(pool *p, const char *name, array_header **group_ids,
}
}
- if (cmd->tmp_pool) {
+ if (cmd->tmp_pool != NULL) {
destroy_pool(cmd->tmp_pool);
cmd->tmp_pool = NULL;
}
=====================================
src/event.c
=====================================
@@ -160,8 +160,8 @@ int pr_event_register(module *m, const char *event,
}
if (evh->module != NULL) {
- if (evl->handlers->next != NULL) {
- evl->handlers->next->prev = evh;
+ if (evl->handlers != NULL) {
+ evl->handlers->prev = evh;
}
evh->next = evl->handlers;
=====================================
src/fsio.c
=====================================
@@ -2,7 +2,7 @@
* ProFTPD - FTP server daemon
* Copyright (c) 1997, 1998 Public Flood Software
* Copyright (c) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver at tos.net>
- * Copyright (c) 2001-2022 The ProFTPD Project
+ * Copyright (c) 2001-2024 The ProFTPD Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -699,11 +699,11 @@ static ssize_t unix_flistxattr(int fd, char *namelist, size_t len) {
static int sys_listxattr(pool *p, pr_fs_t *fs, const char *path,
array_header **names) {
- ssize_t res;
+ ssize_t res = 0;
char *namelist = NULL;
size_t len = 0;
-#ifdef PR_USE_XATTR
+#if defined(PR_USE_XATTR)
/* We need to handle the different formats of namelists that listxattr et al
* can provide. On *BSDs, the namelist buffer uses length prefixes and no
* terminating NULs; on Linux/Mac, the namelist buffer uses ONLY
@@ -720,6 +720,13 @@ static int sys_listxattr(pool *p, pr_fs_t *fs, const char *path,
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "listxattr: found 0 xattr names for '%s'",
+ path);
+ return 0;
+ }
+
len = res;
namelist = palloc(p, len);
@@ -728,6 +735,13 @@ static int sys_listxattr(pool *p, pr_fs_t *fs, const char *path,
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "listxattr: found 0 xattr names for '%s'",
+ path);
+ return 0;
+ }
+
*names = parse_xattr_namelist(p, namelist, len);
if (pr_trace_get_level(trace_channel) >= 15) {
register unsigned int i;
@@ -765,13 +779,20 @@ static int sys_llistxattr(pool *p, pr_fs_t *fs, const char *path,
char *namelist = NULL;
size_t len = 0;
-#ifdef PR_USE_XATTR
+#if defined(PR_USE_XATTR)
/* See sys_listxattr for a description of why we use this approach. */
res = unix_llistxattr(path, NULL, 0);
if (res < 0) {
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "llistxattr: found 0 xattr names for '%s'",
+ path);
+ return 0;
+ }
+
len = res;
namelist = palloc(p, len);
@@ -780,6 +801,13 @@ static int sys_llistxattr(pool *p, pr_fs_t *fs, const char *path,
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "llistxattr: found 0 xattr names for '%s'",
+ path);
+ return 0;
+ }
+
*names = parse_xattr_namelist(p, namelist, len);
if (pr_trace_get_level(trace_channel) >= 15) {
register unsigned int i;
@@ -816,13 +844,20 @@ static int sys_flistxattr(pool *p, pr_fh_t *fh, int fd, array_header **names) {
char *namelist = NULL;
size_t len = 0;
-#ifdef PR_USE_XATTR
+#if defined(PR_USE_XATTR)
/* See sys_listxattr for a description of why we use this approach. */
res = unix_flistxattr(fd, NULL, 0);
if (res < 0) {
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "flistxattr: found 0 xattr names for '%s'",
+ fh->fh_path);
+ return 0;
+ }
+
len = res;
namelist = palloc(p, len);
@@ -831,6 +866,13 @@ static int sys_flistxattr(pool *p, pr_fh_t *fh, int fd, array_header **names) {
return -1;
}
+ if (res == 0) {
+ /* No extended attributes found. */
+ pr_trace_msg(trace_channel, 15, "flistxattr: found 0 xattr names for '%s'",
+ fh->fh_path);
+ return 0;
+ }
+
*names = parse_xattr_namelist(p, namelist, len);
if (pr_trace_get_level(trace_channel) >= 15) {
register unsigned int i;
=====================================
tests/api/inet.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD - FTP server testsuite
- * Copyright (c) 2014-2021 The ProFTPD Project team
+ * Copyright (c) 2014-2024 The ProFTPD Project team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -974,8 +974,13 @@ START_TEST (inet_connect_nowait_test) {
ck_assert_msg(addr != NULL, "Failed to resolve '127.0.0.1': %s",
strerror(errno));
- res = pr_inet_connect_nowait(p, conn, addr, 180);
- ck_assert_msg(res != -1, "Connected to 127.0.0.1#180 unexpectedly");
+ if (getenv("CIRRUS_CLONE_DEPTH") == NULL) {
+ /* On CirrusCI VMs, this succeeds unexpectedly, so run it only when we
+ * are NOT running in the Cirrus CI.
+ */
+ res = pr_inet_connect_nowait(p, conn, addr, 180);
+ ck_assert_msg(res != -1, "Connected to 127.0.0.1#180 unexpectedly");
+ }
#if defined(PR_USE_NETWORK_TESTS)
/* Try connecting to Google's DNS server. */
=====================================
tests/t/lib/ProFTPD/Tests/Modules/mod_sftp.pm
=====================================
@@ -5647,11 +5647,7 @@ EOC
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
-
- # libssh2, and thus Net::SSH2, don't support ECC/ECDH yet. So we
- # use the external sftp(1) client (e.g. OpenSSH-5.9p1) to test.
-
- my $sftp = '/Users/tj/local/openssh-7.9p1/bin/sftp';
+ my $sftp = 'sftp';
my @cmd = (
$sftp,
@@ -5725,9 +5721,7 @@ EOC
my $expected_sz = $src_sz;
$self->assert($expected_sz == $sz,
test_msg("Expected file size $expected_sz, got $sz"));
-
};
-
if ($@) {
$ex = $@;
}
@@ -5898,11 +5892,7 @@ EOC
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
-
- # libssh2, and thus Net::SSH2, don't support ECC/ECDH yet. So we
- # use the external sftp(1) client (e.g. OpenSSH-5.9p1) to test.
-
- my $sftp = '/Users/tj/local/openssh-7.9p1/bin/sftp';
+ my $sftp = 'sftp';
my @cmd = (
$sftp,
@@ -6149,11 +6139,7 @@ EOC
defined(my $pid = fork()) or die("Can't fork: $!");
if ($pid) {
eval {
-
- # libssh2, and thus Net::SSH2, don't support ECC/ECDH yet. So we
- # use the external sftp(1) client (e.g. OpenSSH-5.9p1) to test.
-
- my $sftp = '/Users/tj/local/openssh-7.9p1/bin/sftp';
+ my $sftp = 'sftp';
my @cmd = (
$sftp,
=====================================
tests/t/lib/ProFTPD/Tests/Modules/mod_sftp_sql.pm
=====================================
@@ -98,6 +98,11 @@ my $TESTS = {
test_class => [qw(bug forking ssh2)],
},
+ ssh2_auth_publickey_empty_comment_issue1529 => {
+ order => ++$order,
+ test_class => [qw(bug forking ssh2)],
+ },
+
};
sub new {
@@ -3170,4 +3175,150 @@ EOS
test_cleanup($setup->{log_file}, $ex);
}
+sub ssh2_auth_publickey_empty_comment_issue1529 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'sftp_sql');
+
+ my $db_file = File::Spec->rel2abs("$tmpdir/sftp.db");
+
+ my $rsa_rfc4716_data = '---- BEGIN SSH2 PUBLIC KEY ----
+Comment:
+AAAAB3NzaC1yc2EAAAABIwAAAQEAzJ1CLwnVP9mUa8uyM+XBzxLxsRvGz4cS59aPTgdw7j
+Gx1jCvC9ya400x7ej5Q4ubwlAAPblXzG5GYv2ROmYQ1DIjrhmR/61tDKUvAAZIgtvLZ00y
+dqqpq5lG4ubVJ4gW6sxbPfq/X12kV1gxGsFLUJCgoYInZGyIONrnvmQjFIfIx+mQXaK84u
+O6w0CT6KhRWgonajMrlO6P8O7qr80rFmOZsBNIMooyYrGTaMyxVsQK2SY+VKbXWFC+2HMm
+ef62n+02ohAOBKtOsSOn8HE2wi7yMA0g8jRTd8kZcWBIkAhizPvl8pqG1F0DCmLn00rhPk
+Byq2pv4VBo953gK7f1AQ==
+---- END SSH2 PUBLIC KEY ----';
+
+ my $db_script = File::Spec->rel2abs("$tmpdir/sftp.sql");
+
+ my $fh;
+ if (open($fh, "> $db_script")) {
+ print $fh <<EOS;
+CREATE TABLE sftpuserkeys (
+ name TEXT NOT NULL PRIMARY KEY,
+ key BLOB NOT NULL
+);
+
+INSERT INTO sftpuserkeys (name, key) VALUES ('$setup->{user}', '$rsa_rfc4716_data');
+EOS
+ unless (close($fh)) {
+ die("Can't write $db_script: $!");
+ }
+
+ } else {
+ die("Can't open $db_script: $!");
+ }
+
+ my $cmd = "sqlite3 $db_file < $db_script";
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "Executing sqlite3: $cmd\n";
+ }
+
+ my @output = `$cmd`;
+
+ unlink($db_script);
+
+ my $rsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_rsa_key');
+ my $dsa_host_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/ssh_host_dsa_key');
+
+ my $rsa_priv_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key');
+ my $rsa_pub_key = File::Spec->rel2abs('t/etc/modules/mod_sftp/test_rsa_key.pub');
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+ TraceLog => $setup->{log_file},
+ Trace => 'ssh2:20 sftp:20 sql:20',
+
+ AuthUserFile => $setup->{auth_user_file},
+ AuthGroupFile => $setup->{auth_group_file},
+ AuthOrder => 'mod_auth_file.c',
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+
+ 'mod_sql_sqlite.c' => {
+ SQLAuthenticate => 'off',
+ SQLConnectInfo => $db_file,
+ SQLLogFile => $setup->{log_file},
+ SQLNamedQuery => 'get-user-authorized-keys SELECT "key FROM sftpuserkeys WHERE name = \'%{0}\'"',
+ },
+
+ 'mod_sftp.c' => [
+ "SFTPEngine on",
+ "SFTPLog $setup->{log_file}",
+ "SFTPHostKey $rsa_host_key",
+ "SFTPHostKey $dsa_host_key",
+ "SFTPAuthorizedUserKeys sql:/get-user-authorized-keys",
+ ],
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ require Net::SSH2;
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ # Allow for server startup
+ sleep(2);
+
+ my $ssh2 = Net::SSH2->new();
+
+ unless ($ssh2->connect('127.0.0.1', $port)) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("Can't connect to SSH2 server: [$err_name] ($err_code) $err_str");
+ }
+
+ unless ($ssh2->auth_publickey($setup->{user}, $rsa_pub_key, $rsa_priv_key)) {
+ my ($err_code, $err_name, $err_str) = $ssh2->error();
+ die("RSA publickey authentication failed: [$err_name] ($err_code) $err_str");
+ }
+
+ $ssh2->disconnect();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
1;
=====================================
tests/t/lib/ProFTPD/Tests/Modules/mod_sql_sqlite.pm
=====================================
@@ -467,6 +467,11 @@ my $TESTS = {
order => ++$order,
test_class => [qw(forking bug mod_tls)],
},
+
+ sql_user_info_no_suppl_groups_issue1830 => {
+ order => ++$order,
+ test_class => [qw(forking bug rootprivs)],
+ },
};
sub new {
@@ -15764,4 +15769,173 @@ EOC
test_cleanup($setup->{log_file}, $ex);
}
+sub sql_user_info_no_suppl_groups_issue1830 {
+ my $self = shift;
+ my $tmpdir = $self->{tmpdir};
+ my $setup = test_setup($tmpdir, 'sqlite');
+
+ my $db_file = File::Spec->rel2abs("$tmpdir/proftpd.db");
+
+ # Build up sqlite3 command to create users, groups tables and populate them
+ my $db_script = File::Spec->rel2abs("$tmpdir/proftpd.sql");
+
+ if (open(my $fh, "> $db_script")) {
+ print $fh <<EOS;
+CREATE TABLE users (
+ userid TEXT,
+ passwd TEXT,
+ uid INTEGER,
+ gid INTEGER,
+ homedir TEXT,
+ shell TEXT
+);
+INSERT INTO users (userid, passwd, uid, gid, homedir, shell) VALUES ('$setup->{user}', '$setup->{passwd}', $setup->{uid}, $setup->{gid}, '$setup->{home_dir}', '/bin/bash');
+
+CREATE TABLE groups (
+ groupname TEXT,
+ gid INTEGER,
+ members TEXT
+);
+INSERT INTO groups (groupname, gid, members) VALUES ('$setup->{group}', $setup->{gid}, '$setup->{user}');
+EOS
+
+ unless (close($fh)) {
+ die("Can't write $db_script: $!");
+ }
+
+ } else {
+ die("Can't open $db_script: $!");
+ }
+
+ my $cmd = "sqlite3 $db_file < $db_script";
+ build_db($cmd, $db_script);
+
+ # Make sure that, if we're running as root, the database file has
+ # the permissions/privs set for use by proftpd
+ if ($< == 0) {
+ unless (chmod(0666, $db_file)) {
+ die("Can't set perms on $db_file to 0666: $!");
+ }
+ }
+
+ my $config = {
+ PidFile => $setup->{pid_file},
+ ScoreboardFile => $setup->{scoreboard_file},
+ SystemLog => $setup->{log_file},
+ TraceLog => $setup->{log_file},
+ Trace => 'auth:20 sql:20',
+
+ # Required for logging the expected message
+ DebugLevel => 5,
+
+ IfModules => {
+ 'mod_delay.c' => {
+ DelayEngine => 'off',
+ },
+
+ 'mod_sql.c' => {
+ AuthOrder => 'mod_sql.c',
+
+ SQLAuthenticate => 'users',
+ SQLAuthTypes => 'plaintext',
+ SQLBackend => 'sqlite3',
+ SQLConnectInfo => $db_file,
+ SQLLogFile => $setup->{log_file},
+
+ # Set these, so that our lower UID/GID will be used
+ SQLMinUserUID => 100,
+ SQLMinUserGID => 100,
+ },
+ },
+ };
+
+ my ($port, $config_user, $config_group) = config_write($setup->{config_file},
+ $config);
+
+ # Open pipes, for use between the parent and child processes. Specifically,
+ # the child will indicate when it's done with its test by writing a message
+ # to the parent.
+ my ($rfh, $wfh);
+ unless (pipe($rfh, $wfh)) {
+ die("Can't open pipe: $!");
+ }
+
+ my $ex;
+
+ # Fork child
+ $self->handle_sigchld();
+ defined(my $pid = fork()) or die("Can't fork: $!");
+ if ($pid) {
+ eval {
+ sleep(2);
+
+ my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
+ $client->login($setup->{user}, $setup->{passwd});
+
+ my $resp_msgs = $client->response_msgs();
+ my $nmsgs = scalar(@$resp_msgs);
+
+ my $expected = 1;
+ $self->assert($expected == $nmsgs,
+ test_msg("Expected $expected, got $nmsgs"));
+
+ $expected = "User $setup->{user} logged in";
+ $self->assert($expected eq $resp_msgs->[0],
+ test_msg("Expected response '$expected', got '$resp_msgs->[0]'"));
+
+ $client->quit();
+ };
+ if ($@) {
+ $ex = $@;
+ }
+
+ $wfh->print("done\n");
+ $wfh->flush();
+
+ } else {
+ eval { server_wait($setup->{config_file}, $rfh) };
+ if ($@) {
+ warn($@);
+ exit 1;
+ }
+
+ exit 0;
+ }
+
+ # Stop server
+ server_stop($setup->{pid_file});
+ $self->assert_child_ok($pid);
+
+ eval {
+ if (open(my $fh, "< $setup->{log_file}")) {
+ my $ok = 0;
+
+ while (my $line = <$fh>) {
+ chomp($line);
+
+ if ($ENV{TEST_VERBOSE}) {
+ print STDERR "# $line\n";
+ }
+
+ if ($line =~ /no supplemental groups found for user '$setup->{user}', using primary group/) {
+ $ok = 1;
+ last;
+ }
+ }
+
+ close($fh);
+
+ $self->assert($ok, test_msg("Did not see expected log message"));
+
+ } else {
+ die("Can't read $setup->{log_file}: $!");
+ }
+ };
+ if ($@) {
+ $ex = $@ unless $ex;
+ }
+
+ test_cleanup($setup->{log_file}, $ex);
+}
+
1;
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd/-/commit/91f64bbe1f6597e058f4880c530d5c24c278ee64
--
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd/-/commit/91f64bbe1f6597e058f4880c530d5c24c278ee64
You're receiving this email because of your account on salsa.debian.org.
More information about the Pkg-proftpd-maintainers
mailing list