1 #define LIBSSH_STATIC
2
3 #include "config.h"
4
5 #include "torture.h"
6 #include "sftp.c"
7
8 #include <sys/types.h>
9 #include <pwd.h>
10 #include <errno.h>
11
12 #define MAX_XFER_BUF_SIZE 16384
13
sshd_setup(void ** state)14 static int sshd_setup(void **state)
15 {
16 torture_setup_sshd_server(state, false);
17
18 return 0;
19 }
20
sshd_teardown(void ** state)21 static int sshd_teardown(void **state) {
22 torture_teardown_sshd_server(state);
23
24 return 0;
25 }
26
session_setup(void ** state)27 static int session_setup(void **state)
28 {
29 struct torture_state *s = *state;
30 struct passwd *pwd;
31 int rc;
32
33 pwd = getpwnam("bob");
34 assert_non_null(pwd);
35
36 rc = setuid(pwd->pw_uid);
37 assert_return_code(rc, errno);
38
39 s->ssh.session = torture_ssh_session(s,
40 TORTURE_SSH_SERVER,
41 NULL,
42 TORTURE_SSH_USER_ALICE,
43 NULL);
44 assert_non_null(s->ssh.session);
45
46 s->ssh.tsftp = torture_sftp_session(s->ssh.session);
47 assert_non_null(s->ssh.tsftp);
48
49 return 0;
50 }
51
session_teardown(void ** state)52 static int session_teardown(void **state)
53 {
54 struct torture_state *s = *state;
55
56 torture_rmdirs(s->ssh.tsftp->testdir);
57 torture_sftp_close(s->ssh.tsftp);
58 ssh_disconnect(s->ssh.session);
59 ssh_free(s->ssh.session);
60
61 return 0;
62 }
63
torture_sftp_read_blocking(void ** state)64 static void torture_sftp_read_blocking(void **state) {
65 struct torture_state *s = *state;
66 struct torture_sftp *t = s->ssh.tsftp;
67
68 char libssh_tmp_file[] = "/tmp/libssh_sftp_test_XXXXXX";
69 char buf[MAX_XFER_BUF_SIZE];
70 ssize_t bytesread;
71 ssize_t byteswritten;
72 int fd;
73 sftp_file file;
74 mode_t mask;
75
76 file = sftp_open(t->sftp, SSH_EXECUTABLE, O_RDONLY, 0);
77 assert_non_null(file);
78
79 mask = umask(S_IRWXO | S_IRWXG);
80 fd = mkstemp(libssh_tmp_file);
81 umask(mask);
82 unlink(libssh_tmp_file);
83
84 for (;;) {
85 bytesread = sftp_read(file, buf, MAX_XFER_BUF_SIZE);
86 if (bytesread == 0) {
87 break; /* EOF */
88 }
89 assert_false(bytesread < 0);
90
91 byteswritten = write(fd, buf, bytesread);
92 assert_int_equal(byteswritten, bytesread);
93 }
94
95 close(fd);
96 sftp_close(file);
97 }
98
torture_run_tests(void)99 int torture_run_tests(void) {
100 int rc;
101 struct CMUnitTest tests[] = {
102 /* This test is intentionally running twice to trigger a bug in OpenSSH
103 * or in pam_wrapper, causing the second invocation to fail.
104 * See: https://bugs.libssh.org/T122
105 */
106 cmocka_unit_test_setup_teardown(torture_sftp_read_blocking,
107 session_setup,
108 session_teardown),
109 cmocka_unit_test_setup_teardown(torture_sftp_read_blocking,
110 session_setup,
111 session_teardown)
112 };
113
114 ssh_init();
115
116 torture_filter_tests(tests);
117 rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
118 ssh_finalize();
119
120 return rc;
121 }
122