1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
#define LIBSSH_STATIC
#include "config.h"
#include "torture.h"
#include "sftp.c"
#include <sys/types.h>
#include <sys/resource.h>
#include <pwd.h>
#include <errno.h>
#if HAVE_VALGRIND_VALGRIND_H
#include <valgrind/valgrind.h>
#endif
static int sshd_setup(void **state)
{
torture_setup_sshd_server(state, false);
return 0;
}
static int sshd_teardown(void **state)
{
torture_teardown_sshd_server(state);
return 0;
}
static int session_setup(void **state)
{
struct torture_state *s = *state;
struct passwd *pwd = NULL;
int rc;
pwd = getpwnam("bob");
assert_non_null(pwd);
rc = setuid(pwd->pw_uid);
assert_return_code(rc, errno);
s->ssh.session = torture_ssh_session(s,
TORTURE_SSH_SERVER,
NULL,
TORTURE_SSH_USER_ALICE,
NULL);
assert_non_null(s->ssh.session);
s->ssh.tsftp = torture_sftp_session(s->ssh.session);
assert_non_null(s->ssh.tsftp);
return 0;
}
static int session_teardown(void **state)
{
struct torture_state *s = *state;
torture_rmdirs(s->ssh.tsftp->testdir);
torture_sftp_close(s->ssh.tsftp);
ssh_disconnect(s->ssh.session);
ssh_free(s->ssh.session);
return 0;
}
static void torture_sftp_limits(void **state)
{
struct torture_state *s = *state;
struct torture_sftp *t = s->ssh.tsftp;
sftp_limits_t li = NULL;
int rc;
li = sftp_limits(t->sftp);
assert_non_null(li);
rc = sftp_extension_supported(t->sftp, "limits@openssh.com", "1");
if (rc == 1) {
/*
* Tests are run against the OpenSSH server, hence we check for the
* specific limits used by OpenSSH.
*/
uint64_t openssh_max_packet_length = 256 * 1024;
uint64_t openssh_max_read_length = openssh_max_packet_length - 1024;
uint64_t openssh_max_write_length = openssh_max_packet_length - 1024;
size_t vg = 0;
assert_int_equal(li->max_packet_length, openssh_max_packet_length);
assert_int_equal(li->max_read_length, openssh_max_read_length);
assert_int_equal(li->max_write_length, openssh_max_write_length);
/*
* fds - File descriptors, w.r.to - With respect to
*
* Valgrind reserves some fds for itself and changes the rlimits
* w.r.to fds for the process its inspecting. Due to this reservation
* the rlimits w.r.to fds for our test may not be the same as the
* rlimits w.r.to fds seen by OpenSSH server (which Valgrind isn't
* inspecting).
*
* Valgrind changes the limits in such a way that after seeing the
* changed limits, the test cannot predict the original unchanged
* limits (which OpenSSH would be using). Hence, the test cannot
* determine the correct value of "max_open_handles" that the OpenSSH
* server should've sent.
*
* So if Valgrind is running our test, we don't provide any kind of
* check for max_open_handles. Check for >= 0 is also not provided in
* this case since that's always true for an uint64_t (an unsigned type)
*/
#if HAVE_VALGRIND_VALGRIND_H
vg = RUNNING_ON_VALGRIND;
#endif
if (vg == 0) {
struct rlimit rlim = {0};
uint64_t openssh_max_open_handles = 0;
/*
* Get the resource limit for max file descriptors that a process
* can open. Since the client and the server run on the same machine
* in case of tests, this limit should be same for both (except the
* case when Valgrind runs the test)
*/
rc = getrlimit(RLIMIT_NOFILE, &rlim);
assert_int_equal(rc, 0);
if (rlim.rlim_cur > 5) {
/*
* Leaving file handles for stdout, stdin, stderr, syslog and
* a spare file handle, OpenSSH server allows the client to open
* at max (rlim.rlim_cur - 5) handles.
*/
openssh_max_open_handles = rlim.rlim_cur - 5;
}
assert_int_equal(li->max_open_handles, openssh_max_open_handles);
}
} else {
/* Check for the default limits */
assert_int_equal(li->max_packet_length, 34000);
assert_int_equal(li->max_read_length, 32768);
assert_int_equal(li->max_write_length, 32768);
assert_int_equal(li->max_open_handles, 0);
}
sftp_limits_free(li);
}
static void torture_sftp_limits_negative(void **state)
{
sftp_limits_t li = NULL;
(void)state;
li = sftp_limits(NULL);
assert_null(li);
}
int torture_run_tests(void)
{
int rc;
struct CMUnitTest tests[] = {
cmocka_unit_test_setup_teardown(torture_sftp_limits,
session_setup,
session_teardown),
cmocka_unit_test_setup_teardown(torture_sftp_limits_negative,
session_setup,
session_teardown)
};
ssh_init();
torture_filter_tests(tests);
rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
ssh_finalize();
return rc;
}
|