aboutsummaryrefslogtreecommitdiff
path: root/tests/client/torture_sftp_fsync.c
blob: 02e22e095cc738c0cfdc7ded39cb75807f8b4850 (plain)
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
#define LIBSSH_STATIC

#include "torture.h"
#include "sftp.c"

#include <sys/types.h>
#include <pwd.h>

#define MAX_XFER_BUF_SIZE 16384

static int sshd_setup(void **state)
{
    torture_setup_sshd_server(state);

    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;

    pwd = getpwnam("bob");
    assert_non_null(pwd);
    setuid(pwd->pw_uid);

    s->ssh.session = torture_ssh_session(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_fsync(void **state) {
    struct torture_state *s = *state;
    struct torture_sftp *t = s->ssh.tsftp;

    char libssh_tmp_file[] = "/tmp/libssh_sftp_test_XXXXXX";
    char buf[MAX_XFER_BUF_SIZE] = {0};
    char buf_verify[MAX_XFER_BUF_SIZE] = {0};
    size_t count;
    size_t bytesread;
    ssize_t byteswritten;
    int fd;
    sftp_file file;
    mode_t mask;
    int rc;
    FILE *fp;
    struct stat sb;

    mask = umask(S_IRWXO | S_IRWXG);
    fd = mkstemp(libssh_tmp_file);
    umask(mask);
    assert_return_code(fd, errno);
    close(fd);
    unlink(libssh_tmp_file);

    file = sftp_open(t->sftp, libssh_tmp_file, O_WRONLY | O_CREAT, 0600);
    assert_non_null(file);

    rc = lstat(libssh_tmp_file, &sb);
    assert_return_code(rc, errno);

    snprintf(buf, sizeof(buf), "libssh fsync test\n");
    count = strlen(buf) + 1;

    byteswritten = sftp_write(file, buf, count);
    assert_int_equal(byteswritten, count);

    rc = sftp_fsync(file);
    assert_return_code(rc, errno);

    fp = fopen(libssh_tmp_file, "r");
    assert_non_null(fp);

    rc = lstat(libssh_tmp_file, &sb);
    assert_return_code(rc, errno);

    bytesread = fread(buf_verify, sizeof(buf_verify), 1, fp);
    if (bytesread == 0) {
        if (!feof(fp)) {
            assert_int_equal(bytesread, count);
        }
    }
    assert_string_equal(buf, buf_verify);

    sftp_close(file);
    fclose(fp);
    unlink(libssh_tmp_file);
}

int torture_run_tests(void) {
    int rc;
    struct CMUnitTest tests[] = {
        cmocka_unit_test_setup_teardown(torture_sftp_fsync,
                                        session_setup,
                                        session_teardown)
    };

    ssh_init();

    torture_filter_tests(tests);
    rc = cmocka_run_group_tests(tests, sshd_setup, sshd_teardown);
    ssh_finalize();

    return rc;
}