[Git][debian-proftpd-team/proftpd-mod-vroot][upstream] New upstream version 0.9.10
Hilmar Preuße (@hilmar-guest)
gitlab at salsa.debian.org
Wed Aug 3 22:10:16 BST 2022
Hilmar Preuße pushed to branch upstream at Debian ProFTPD Team / proftpd-mod-vroot
Commits:
6cb9f505 by Hilmar Preusse at 2022-08-03T23:07:05+02:00
New upstream version 0.9.10
- - - - -
6 changed files:
- .gitignore
- path.c
- t/Makefile.in
- t/api/alias.c
- t/api/fsio.c
- t/api/path.c
Changes:
=====================================
.gitignore
=====================================
@@ -3,6 +3,7 @@ Makefile
config.status
autom4te.cache
mod_vroot.h
+t/api-tests
.libs
.*.swp
*.la
=====================================
path.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD: mod_vroot Path API
- * Copyright (c) 2016 TJ Saunders
+ * Copyright (c) 2016-2022 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
@@ -69,18 +69,25 @@ const char *vroot_path_get_base(pool *p, size_t *baselen) {
}
int vroot_path_set_base(const char *base, size_t baselen) {
- if (base == NULL) {
+ if (base == NULL ||
+ baselen >= sizeof(vroot_base)) {
errno = EINVAL;
return -1;
}
memset(vroot_base, '\0', sizeof(vroot_base));
- memcpy(vroot_base, base, sizeof(vroot_base)-1);
+ if (baselen > 0) {
+ memcpy(vroot_base, base, baselen);
+ vroot_base[sizeof(vroot_base)-1] = '\0';
+ }
vroot_baselen = baselen;
return 0;
}
+/* Note that we do in-place modifications of the given `path` buffer here,
+ * which means that it MUST be writable; no constant strings, please.
+ */
void vroot_path_clean(char *path) {
char *ptr = NULL;
@@ -91,17 +98,23 @@ void vroot_path_clean(char *path) {
ptr = strstr(path, "//");
while (ptr != NULL) {
+ pr_signals_handle();
+
strmove(ptr, ptr + 1);
ptr = strstr(path, "//");
}
ptr = strstr(path, "/./");
while (ptr != NULL) {
+ pr_signals_handle();
+
strmove(ptr, ptr + 2);
ptr = strstr(path, "/./");
}
while (strncmp(path, "../", 3) == 0) {
+ pr_signals_handle();
+
path += 3;
}
@@ -109,6 +122,8 @@ void vroot_path_clean(char *path) {
if (ptr != NULL) {
if (ptr == path) {
while (strncmp(path, "/../", 4) == 0) {
+ pr_signals_handle();
+
strmove(path, path + 3);
}
@@ -116,7 +131,11 @@ void vroot_path_clean(char *path) {
}
while (ptr != NULL) {
- char *next_elem = ptr + 4;
+ char *next_elem;
+
+ pr_signals_handle();
+
+ next_elem = ptr + 4;
if (ptr != path &&
*ptr == '/') {
@@ -197,14 +216,16 @@ char *vroot_realpath(pool *p, const char *path, int flags) {
char *real_path = NULL;
size_t real_pathlen;
- if (flags & VROOT_REALPATH_FL_ABS_PATH) {
- /* If not an absolute path, prepend the current location. */
- if (*path != '/') {
- real_path = pdircat(p, pr_fs_getvwd(), path, NULL);
+ if (p == NULL ||
+ path == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
- } else {
- real_path = pstrdup(p, path);
- }
+ /* If not an absolute path, prepend the current location. */
+ if (*path != '/' &&
+ (flags & VROOT_REALPATH_FL_ABS_PATH)) {
+ real_path = pdircat(p, pr_fs_getvwd(), path, NULL);
} else {
real_path = pstrdup(p, path);
@@ -225,18 +246,31 @@ char *vroot_realpath(pool *p, const char *path, int flags) {
return real_path;
}
-int vroot_path_lookup(pool *p, char *path, size_t pathlen, const char *dir,
+/* The given `vpath` buffer is the looked-up path for the given `path`. */
+int vroot_path_lookup(pool *p, char *vpath, size_t vpathsz, const char *path,
int flags, char **alias_path) {
char buf[PR_TUNABLE_PATH_MAX + 1], *bufp = NULL;
+ const char *cwd;
+
+ if (vpath == NULL ||
+ path == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
memset(buf, '\0', sizeof(buf));
- memset(path, '\0', pathlen);
+ if (vpath != NULL &&
+ vpathsz > 0) {
+ memset(vpath, '\0', vpathsz);
+ }
+
+ cwd = pr_fs_getcwd();
- if (strcmp(dir, ".") != 0) {
- sstrncpy(buf, dir, sizeof(buf));
+ if (strcmp(path, ".") != 0) {
+ sstrncpy(buf, path, sizeof(buf));
} else {
- sstrncpy(buf, pr_fs_getcwd(), sizeof(buf));
+ sstrncpy(buf, cwd, sizeof(buf));
}
vroot_path_clean(buf);
@@ -244,7 +278,17 @@ int vroot_path_lookup(pool *p, char *path, size_t pathlen, const char *dir,
bufp = buf;
if (strncmp(bufp, vroot_base, vroot_baselen) == 0) {
- bufp += vroot_baselen;
+ size_t len;
+
+ /* Attempt to handle cases like "/base/base" and "/base/basefoo", where
+ * the base is just "/base".
+ * See https://github.com/proftpd/proftpd/issues/1491
+ */
+ len = strlen(bufp);
+ if (len > vroot_baselen &&
+ bufp[vroot_baselen] == '/') {
+ bufp += vroot_baselen;
+ }
}
loop:
@@ -254,19 +298,19 @@ loop:
bufp[1] == '.' &&
(bufp[2] == '\0' ||
bufp[2] == '/')) {
- char *tmp = NULL;
+ char *ptr = NULL;
- tmp = strrchr(path, '/');
- if (tmp != NULL) {
- *tmp = '\0';
+ ptr = strrchr(vpath, '/');
+ if (ptr != NULL) {
+ *ptr = '\0';
} else {
- *path = '\0';
+ *vpath = '\0';
}
- if (strncmp(path, vroot_base, vroot_baselen) == 0 ||
- path[vroot_baselen] != '/') {
- snprintf(path, pathlen, "%s/", vroot_base);
+ if (strncmp(vpath, vroot_base, vroot_baselen) == 0 ||
+ vpath[vroot_baselen] != '/') {
+ snprintf(vpath, vpathsz, "%s/", vroot_base);
}
if (bufp[0] == '.' &&
@@ -277,7 +321,7 @@ loop:
}
} else if (*bufp == '/') {
- snprintf(path, pathlen, "%s/", vroot_base);
+ snprintf(vpath, vpathsz, "%s/", vroot_base);
bufp += 1;
goto loop;
@@ -319,19 +363,19 @@ loop:
}
buflen = strlen(bufp) + 1;
- tmplen = strlen(path);
+ tmplen = strlen(vpath);
- if (tmplen + buflen >= pathlen) {
+ if (tmplen + buflen >= vpathsz) {
errno = ENAMETOOLONG;
return -1;
}
- path[tmplen] = '/';
- memcpy(path + tmplen + 1, bufp, buflen);
+ vpath[tmplen] = '/';
+ memcpy(vpath + tmplen + 1, bufp, buflen);
}
/* Clean any unnecessary characters added by the above processing. */
- vroot_path_clean(path);
+ vroot_path_clean(vpath);
if (!(flags & VROOT_LOOKUP_FL_NO_ALIAS)) {
int alias_count;
@@ -346,7 +390,7 @@ loop:
* aliases are found.
*/
bufp = buf;
- start_ptr = path;
+ start_ptr = vpath;
while (start_ptr != NULL) {
char *ptr = NULL;
@@ -376,11 +420,11 @@ loop:
*alias_path, start_ptr);
}
- sstrncpy(path, src_path, pathlen);
+ sstrncpy(vpath, src_path, vpathsz);
if (end_ptr != NULL) {
/* Now tack on our suffix from the scratchpad. */
- sstrcat(path, bufp, pathlen);
+ sstrcat(vpath, bufp, vpathsz);
}
break;
@@ -409,5 +453,11 @@ loop:
}
}
+ /* Note that logging the session.chroot_path here will not help; mod_vroot
+ * deliberately always sets that to just "/".
+ */
+ pr_trace_msg(trace_channel, 19,
+ "lookup: path = '%s', cwd = '%s', base = '%s', vpath = '%s'", path, cwd,
+ vroot_base, vpath);
return 0;
}
=====================================
t/Makefile.in
=====================================
@@ -23,6 +23,8 @@ TEST_API_DEPS=\
$(top_srcdir)/src/str.o \
$(top_srcdir)/src/sets.o \
$(top_srcdir)/src/table.o \
+ $(top_srcdir)/src/netacl.o \
+ $(top_srcdir)/src/class.o \
$(top_srcdir)/src/event.o \
$(top_srcdir)/src/timers.o \
$(top_srcdir)/src/stash.o \
=====================================
t/api/alias.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_vroot testsuite
- * Copyright (c) 2016 TJ Saunders <tj at castaglia.org>
+ * Copyright (c) 2016-2022 TJ Saunders <tj at castaglia.org>
*
* 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
@@ -58,8 +58,8 @@ START_TEST (alias_init_test) {
int res;
res = vroot_alias_init(NULL);
- fail_unless(res < 0, "Failed to handle null pool");
- fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
+ ck_assert_msg(res < 0, "Failed to handle null pool");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
}
END_TEST
@@ -68,7 +68,7 @@ START_TEST (alias_count_test) {
unsigned int res;
res = vroot_alias_count();
- fail_unless(res == 0, "Expected 0, got %u", res);
+ ck_assert_msg(res == 0, "Expected 0, got %u", res);
}
END_TEST
@@ -77,11 +77,11 @@ START_TEST (alias_exists_test) {
const char *path;
res = vroot_alias_exists(NULL);
- fail_unless(res == FALSE, "Failed to handle null path");
+ ck_assert_msg(res == FALSE, "Failed to handle null path");
path = "/foo/bar";
res = vroot_alias_exists(path);
- fail_unless(res == FALSE, "Expected FALSE for path '%s', got TRUE", path);
+ ck_assert_msg(res == FALSE, "Expected FALSE for path '%s', got TRUE", path);
}
END_TEST
@@ -90,19 +90,19 @@ START_TEST (alias_add_test) {
const char *dst, *src;
res = vroot_alias_add(NULL, NULL);
- fail_unless(res < 0, "Failed to handle null dst");
- fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
+ ck_assert_msg(res < 0, "Failed to handle null dst");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
dst = "foo";
res = vroot_alias_add(dst, NULL);
- fail_unless(res < 0, "Failed to handle null src");
- fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
+ ck_assert_msg(res < 0, "Failed to handle null src");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
src = "bar";
res = vroot_alias_add(dst, src);
- fail_unless(res == 0, "Failed to add alias '%s => %s': %s", src, dst,
+ ck_assert_msg(res == 0, "Failed to add alias '%s => %s': %s", src, dst,
strerror(errno));
}
END_TEST
@@ -111,15 +111,15 @@ START_TEST (alias_get_test) {
const char *alias, *path;
alias = vroot_alias_get(NULL);
- fail_unless(alias == NULL, "Failed to handle null path");
- fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
+ ck_assert_msg(alias == NULL, "Failed to handle null path");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
path = "/foo/bar";
alias = vroot_alias_get(path);
- fail_unless(alias == NULL, "Expected null for path '%s', got '%s'", path,
+ ck_assert_msg(alias == NULL, "Expected null for path '%s', got '%s'", path,
alias);
- fail_unless(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
+ ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
strerror(errno), errno);
}
END_TEST
@@ -128,8 +128,8 @@ START_TEST (alias_do_test) {
int res;
res = vroot_alias_do(NULL, NULL);
- fail_unless(res < 0, "Failed to handle null callback");
- fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
+ ck_assert_msg(res < 0, "Failed to handle null callback");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);
}
END_TEST
=====================================
t/api/fsio.c
=====================================
@@ -50,6 +50,9 @@ static void tear_down(void) {
}
}
+/* TODO: Fill in these FSIO API tests, once the Path API unit tests are
+ * fleshed out more completely, as the FSIO API heavily relies on the Path API.
+ */
START_TEST (fsio_stat_test) {
}
END_TEST
=====================================
t/api/path.c
=====================================
@@ -1,6 +1,6 @@
/*
* ProFTPD - mod_vroot testsuite
- * Copyright (c) 2016 TJ Saunders <tj at castaglia.org>
+ * Copyright (c) 2016-2022 TJ Saunders <tj at castaglia.org>
*
* 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
@@ -40,25 +40,352 @@ static void set_up(void) {
}
static void tear_down(void) {
+ (void) vroot_path_set_base("", 0);
+
if (getenv("TEST_VERBOSE") != NULL) {
pr_trace_set_levels("vroot.path", 0, 0);
}
- if (p) {
+ if (p != NULL) {
destroy_pool(p);
p = NULL;
}
}
+START_TEST (path_have_base_test) {
+ int res;
+
+ mark_point();
+ res = vroot_path_have_base();
+ ck_assert_msg(res == FALSE, "Have vroot base unexpectedly");
+}
+END_TEST
+
+START_TEST (path_get_base_test) {
+ const char *res;
+
+ mark_point();
+ res = vroot_path_get_base(NULL, NULL);
+ ck_assert_msg(res == NULL, "Failed to handle null pool");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ res = vroot_path_get_base(p, NULL);
+ ck_assert_msg(res != NULL, "Failed to get base: %s", strerror(errno));
+ ck_assert_msg(strcmp(res, "") == 0, "Expected '', got '%s'", res);
+}
+END_TEST
+
+START_TEST (path_set_base_test) {
+ int res;
+ const char *path, *ptr;
+ size_t pathlen, len;
+
+ mark_point();
+ res = vroot_path_set_base(NULL, 0);
+ ck_assert_msg(res < 0, "Failed to handle missing path");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ path = "/foo";
+ pathlen = (PR_TUNABLE_PATH_MAX * 4);
+ res = vroot_path_set_base("foo", pathlen);
+ ck_assert_msg(res < 0, "Failed to handle too-long pathlen");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ path = "/foo";
+ pathlen = strlen(path);
+ res = vroot_path_set_base(path, pathlen);
+ ck_assert_msg(res == 0, "Failed to set base '%s': %s", path, strerror(errno));
+
+ mark_point();
+ res = vroot_path_have_base();
+ ck_assert_msg(res == TRUE, "Have base is unexpectedly false");
+
+ mark_point();
+ ptr = vroot_path_get_base(p, &len);
+ ck_assert_msg(ptr != NULL, "Failed to get base: %s", strerror(errno));
+ ck_assert_msg(len == pathlen, "Expected %lu, got %lu",
+ (unsigned long) pathlen, (unsigned long) len);
+
+ /* Clear the base, using an empty string. */
+ mark_point();
+ path = "";
+ res = vroot_path_set_base(path, 0);
+ ck_assert_msg(res == 0, "Failed to set empty path as base: %s",
+ strerror(errno));
+
+ mark_point();
+ res = vroot_path_have_base();
+ ck_assert_msg(res == FALSE, "Have base is unexpectedly true");
+}
+END_TEST
+
START_TEST (path_clean_test) {
+ char *path, *expected;
+
+ mark_point();
+ vroot_path_clean(NULL);
+
+ mark_point();
+ path = pstrdup(p, "//");
+ expected = "/";
+ vroot_path_clean(path);
+ ck_assert_msg(strcmp(path, expected) == 0, "Expected '%s', got '%s'",
+ expected, path);
+
+ mark_point();
+ path = pstrdup(p, "/foo/./bar//");
+ expected = "/foo/bar/";
+ vroot_path_clean(path);
+ ck_assert_msg(strcmp(path, expected) == 0, "Expected '%s', got '%s'",
+ expected, path);
+
+ mark_point();
+ path = pstrdup(p, "/foo/../bar//");
+ expected = "/bar/";
+ vroot_path_clean(path);
+ ck_assert_msg(strcmp(path, expected) == 0, "Expected '%s', got '%s'",
+ expected, path);
+
+ mark_point();
+ path = pstrdup(p, "/./.././.././bar/./");
+ expected = "/bar/";
+ vroot_path_clean(path);
+ ck_assert_msg(strcmp(path, expected) == 0, "Expected '%s', got '%s'",
+ expected, path);
+
+ mark_point();
+ path = pstrdup(p, ".");
+ expected = ".";
+ vroot_path_clean(path);
+ ck_assert_msg(strcmp(path, expected) == 0, "Expected '%s', got '%s'",
+ expected, path);
}
END_TEST
START_TEST (realpath_test) {
+ char *res, *path, *expected;
+
+ mark_point();
+ res = vroot_realpath(NULL, NULL, 0);
+ ck_assert_msg(res == NULL, "Failed to handle null pool");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ res = vroot_realpath(p, NULL, 0);
+ ck_assert_msg(res == NULL, "Failed to handle null path");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ path = pstrdup(p, "/foo");
+ expected = "/foo";
+ res = vroot_realpath(p, path, 0);
+ ck_assert_msg(res != NULL, "Failed to handle path: '%s'", strerror(errno));
+ ck_assert_msg(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
+ expected, res);
+
+ mark_point();
+ path = pstrdup(p, "/foo/");
+ expected = "/foo";
+ res = vroot_realpath(p, path, 0);
+ ck_assert_msg(res != NULL, "Failed to handle path: '%s'", strerror(errno));
+ ck_assert_msg(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
+ expected, res);
+
+ mark_point();
+ path = pstrdup(p, "/foo//");
+ expected = "/foo";
+ res = vroot_realpath(p, path, 0);
+ ck_assert_msg(res != NULL, "Failed to handle path: '%s'", strerror(errno));
+ ck_assert_msg(strcmp(res, expected) == 0, "Expected '%s', got '%s'",
+ expected, res);
}
END_TEST
START_TEST (path_lookup_test) {
+ int res;
+ char *vpath = NULL;
+ size_t vpathsz = 1024;
+ const char *path;
+
+ mark_point();
+ vpath = pcalloc(p, vpathsz);
+ res = vroot_path_lookup(p, vpath, vpathsz, NULL, 0, NULL);
+ ck_assert_msg(res < 0, "Failed to handle null path");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ path = "/";
+ res = vroot_path_lookup(NULL, NULL, 0, path, 0, NULL);
+ ck_assert_msg(res < 0, "Failed to handle null vpath");
+ ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got '%s' (%d)", EINVAL,
+ strerror(errno), errno);
+
+ mark_point();
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+
+ mark_point();
+ path = ".";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+}
+END_TEST
+
+/* See: https://github.com/proftpd/proftpd/issues/1491 */
+START_TEST (path_lookup_issue1491_test) {
+ int res;
+ char *vpath = NULL;
+ size_t vpathsz = 1024, baselen;
+ const char *base, *path, *expected;
+
+ vpath = pcalloc(p, vpathsz);
+ base = "/store";
+ baselen = strlen(base);
+
+ /* Set the base. */
+ mark_point();
+ res = vroot_path_set_base(base, baselen);
+ ck_assert_msg(res == 0, "Failed to set base '%s': %s", base, strerror(errno));
+
+ /* Start with an absolute path that matches the base. */
+ mark_point();
+ path = base;
+
+ /* NOTE: Yes, this is a surprising expectation; it has to do with the
+ * necessary fixes for Issue #1491. Sigh.
+ */
+ expected = "/store/store";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Then try a relative path whose name matches the base, sans the leading
+ * path delimiter.
+ */
+ mark_point();
+ path = "store";
+ expected = base;
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Next, try a relative path for a file whose name starts with that of
+ * the base.
+ */
+ mark_point();
+ path = "storetest";
+ expected = "/storetest";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Next, use an absolute path for a file whose name starts with that of the
+ * base; this appears to be the root of Issue #1491.
+ */
+ mark_point();
+ path = "/storetest";
+
+ /* NOTE: Yes, this is a surprising expectation; it has to do with the
+ * necessary fixes for Issue #1491. Sigh.
+ */
+ expected = "/store/storetest";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Set the new base. */
+ base = "/store/store";
+ baselen = strlen(base);
+
+ mark_point();
+ res = vroot_path_set_base(base, baselen);
+ ck_assert_msg(res == 0, "Failed to set base '%s': %s", base, strerror(errno));
+
+ /* Start with an absolute path that matches the base. */
+ mark_point();
+ path = base;
+
+ /* NOTE: Yes, this is a surprising expectation; it has to do with the
+ * necessary fixes for Issue #1491. Sigh. This is starting to look a little
+ * ridiculous.
+ */
+ expected = "/store/store/store/store";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Then try a relative path whose name matches the base, sans the leading
+ * path delimiter.
+ */
+ mark_point();
+ path = "store";
+ expected = "/store";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Next, try a relative path for a file whose name starts with that of
+ * the base.
+ */
+ mark_point();
+ path = "storetest";
+ expected = "/storetest";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Next, use an absolute path for a file whose name starts with that of the
+ * base; this appears to be the root of Issue #1491.
+ */
+ mark_point();
+ path = "/storetest";
+
+ /* NOTE: Yes, this is a surprising expectation; it has to do with the
+ * necessary fixes for Issue #1491. Sigh.
+ */
+ expected = "/store/store/storetest";
+ res = vroot_path_lookup(p, vpath, vpathsz, path, 0, NULL);
+ ck_assert_msg(res >= 0, "Failed to lookup vpath for '%s': %s", path,
+ strerror(errno));
+ ck_assert_msg(strcmp(vpath, expected) == 0, "Expected '%s', got '%s'",
+ expected, vpath);
+
+ /* Clear the base, using an empty string. */
+ mark_point();
+ path = "";
+ res = vroot_path_set_base(path, 0);
+ ck_assert_msg(res == 0, "Failed to set empty path as base: %s",
+ strerror(errno));
+}
+END_TEST
+
+/* TODO */
+START_TEST (path_lookup_with_alias_test) {
}
END_TEST
@@ -71,9 +398,14 @@ Suite *tests_get_path_suite(void) {
tcase_add_checked_fixture(testcase, set_up, tear_down);
+ tcase_add_test(testcase, path_have_base_test);
+ tcase_add_test(testcase, path_get_base_test);
+ tcase_add_test(testcase, path_set_base_test);
tcase_add_test(testcase, path_clean_test);
tcase_add_test(testcase, realpath_test);
tcase_add_test(testcase, path_lookup_test);
+ tcase_add_test(testcase, path_lookup_issue1491_test);
+ tcase_add_test(testcase, path_lookup_with_alias_test);
suite_add_tcase(suite, testcase);
return suite;
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd-mod-vroot/-/commit/6cb9f505235ed5a8f6167220955bb2d7481fe8e8
--
View it on GitLab: https://salsa.debian.org/debian-proftpd-team/proftpd-mod-vroot/-/commit/6cb9f505235ed5a8f6167220955bb2d7481fe8e8
You're receiving this email because of your account on salsa.debian.org.
More information about the Pkg-proftpd-maintainers
mailing list