1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3  * Copyright (c) 2017-2018, Intel Corporation
4  *
5  * All rights reserved.
6  ***********************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 
11 #include <inttypes.h>
12 #include <stdio.h>
13 #include <stdbool.h>
14 #include <string.h>
15 
16 #include <setjmp.h>
17 #include <cmocka.h>
18 
19 #include "tss2_tpm2_types.h"
20 
21 #include "util/io.h"
22 #define LOGMODULE test
23 #include "util/log.h"
24 
25 int
__wrap_socket(int domain,int type,int protocol)26 __wrap_socket (
27     int domain,
28     int type,
29     int protocol)
30 {
31     errno = mock_type (int);
32     return mock_type (int);
33 }
34 int
__wrap_connect(int sockfd,const struct sockaddr * addr,socklen_t addrlen)35 __wrap_connect (
36     int sockfd,
37     const struct sockaddr *addr,
38     socklen_t addrlen)
39 {
40     errno = mock_type (int);
41     return mock_type (int);
42 }
43 
44 /*
45  * Wrap the 'recv' system call. The mock queue for this function must have an
46  * integer return value (the number of byts recv'd), as well as a pointer to
47  * a buffer to copy data from to return to the caller.
48  */
49 ssize_t
__wrap_read(int fd,void * buffer,size_t count)50 __wrap_read (int fd, void *buffer, size_t count)
51 {
52     LOG_DEBUG ("%s: reading %zu bytes from fd: %d to buffer at 0x%" PRIxPTR,
53                __func__, count, fd, (uintptr_t)buffer);
54     int r = mock_type (ssize_t);
55     if (r > 0)
56         memset(buffer, 0x66, r);
57     return r;
58 }
59 
60 ssize_t
__wrap_write(int fd,const void * buffer,size_t buffer_size)61 __wrap_write (int fd, const void *buffer, size_t buffer_size)
62 {
63     LOG_DEBUG ("writing %zd bytes from 0x%" PRIxPTR " to fd: %d",
64                buffer_size, (uintptr_t)buffer, fd);
65     return mock_type (ssize_t);
66 }
67 
68 /*
69  * A test case for a successful call to the receive function. This requires
70  * that the context and the command buffer be valid (including the size
71  * field being set appropriately). The result should be an RC indicating
72  * success and the size parameter be updated to reflect the size of the
73  * data received.
74  */
75 static void
write_all_simple_success_test(void ** state)76 write_all_simple_success_test (void **state)
77 {
78     ssize_t ret;
79     uint8_t buf [10];
80 
81     will_return (__wrap_write, sizeof (buf));
82     ret = write_all (99, buf, sizeof (buf));
83     assert_int_equal(ret, sizeof (buf));
84 }
85 /*
86  * This test causes the underlying 'read' operation to return '0' bytes
87  * indicating EOF.
88  */
89 static void
read_all_eof_test(void ** state)90 read_all_eof_test (void **state)
91 {
92     ssize_t ret;
93     uint8_t buf [10];
94 
95     will_return (__wrap_read, 0);
96     ret = read_all (10, buf, sizeof (buf));
97     assert_int_equal (ret, 0);
98 }
99 /*
100  * This test is a minor variation on the 'read_all_eof_test'. We still get
101  * an EOF from the underlying read but only after we get a good read, but one
102  * that's less than what was requested.
103  */
104 static void
read_all_twice_eof(void ** state)105 read_all_twice_eof (void **state)
106 {
107     ssize_t ret;
108     uint8_t buf [10];
109 
110     will_return (__wrap_read, 5);
111     will_return (__wrap_read, 0);
112     ret = read_all (10, buf, 10);
113     assert_int_equal (ret, 5);
114 }
115 /* When passed all NULL values ensure that we get back the expected RC. */
116 static void
socket_connect_test(void ** state)117 socket_connect_test (void **state)
118 {
119     TSS2_RC rc;
120     SOCKET sock;
121 
122     will_return (__wrap_socket, 0);
123     will_return (__wrap_socket, 1);
124     will_return (__wrap_connect, 0);
125     will_return (__wrap_connect, 1);
126     rc = socket_connect ("127.0.0.1", 666, &sock);
127     assert_int_equal (rc, TSS2_RC_SUCCESS);
128 }
129 static void
socket_connect_socket_fail_test(void ** state)130 socket_connect_socket_fail_test (void **state)
131 {
132     TSS2_RC rc;
133     SOCKET sock;
134 
135     will_return (__wrap_socket, EINVAL);
136     will_return (__wrap_socket, -1);
137     rc = socket_connect ("127.0.0.1", 555, &sock);
138     assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
139 }
140 static void
socket_connect_connect_fail_test(void ** state)141 socket_connect_connect_fail_test (void **state)
142 {
143     TSS2_RC rc;
144     SOCKET sock;
145 
146     will_return (__wrap_socket, 0);
147     will_return (__wrap_socket, 1);
148     will_return (__wrap_connect, ENOTSOCK);
149     will_return (__wrap_connect, -1);
150     rc = socket_connect ("127.0.0.1", 444, &sock);
151     assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
152 }
153 
154 /* When passed all NULL values ensure that we get back the expected RC. */
155 static void
socket_ipv6_connect_test(void ** state)156 socket_ipv6_connect_test (void **state)
157 {
158     TSS2_RC rc;
159     SOCKET sock;
160 
161     will_return (__wrap_socket, 0);
162     will_return (__wrap_socket, 1);
163     will_return (__wrap_connect, 0);
164     will_return (__wrap_connect, 1);
165     rc = socket_connect ("::1", 666, &sock);
166     assert_int_equal (rc, TSS2_RC_SUCCESS);
167 }
168 static void
socket_ipv6_connect_socket_fail_test(void ** state)169 socket_ipv6_connect_socket_fail_test (void **state)
170 {
171     TSS2_RC rc;
172     SOCKET sock;
173 
174     will_return (__wrap_socket, EINVAL);
175     will_return (__wrap_socket, -1);
176     rc = socket_connect ("::1", 555, &sock);
177     assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
178 }
179 static void
socket_ipv6_connect_connect_fail_test(void ** state)180 socket_ipv6_connect_connect_fail_test (void **state)
181 {
182     TSS2_RC rc;
183     SOCKET sock;
184 
185     will_return (__wrap_socket, 0);
186     will_return (__wrap_socket, 1);
187     will_return (__wrap_connect, ENOTSOCK);
188     will_return (__wrap_connect, -1);
189     rc = socket_connect ("::1", 444, &sock);
190     assert_int_equal (rc, TSS2_TCTI_RC_IO_ERROR);
191 }
192 
193 static void
socket_connect_null_test(void ** state)194 socket_connect_null_test (void **state)
195 {
196     TSS2_RC rc;
197     SOCKET sock;
198 
199     rc = socket_connect (NULL, 444, &sock);
200     assert_int_equal (rc, TSS2_TCTI_RC_BAD_REFERENCE);
201 }
202 
203 int
main(int argc,char * argv[])204 main (int   argc,
205       char *argv[])
206 {
207     const struct CMUnitTest tests[] = {
208         cmocka_unit_test (write_all_simple_success_test),
209         cmocka_unit_test (read_all_eof_test),
210         cmocka_unit_test (read_all_twice_eof),
211         cmocka_unit_test (socket_connect_test),
212         cmocka_unit_test (socket_connect_null_test),
213         cmocka_unit_test (socket_connect_socket_fail_test),
214         cmocka_unit_test (socket_connect_connect_fail_test),
215         cmocka_unit_test (socket_ipv6_connect_test),
216         cmocka_unit_test (socket_ipv6_connect_socket_fail_test),
217         cmocka_unit_test (socket_ipv6_connect_connect_fail_test),
218     };
219     return cmocka_run_group_tests (tests, NULL, NULL);
220 }
221