Merge branch 'upstream' into tizen
[platform/upstream/gnutls.git] / tests / no-signal.c
1 /*
2  * Copyright (C) 2015 Nikos Mavrogiannopoulos
3  *
4  * This file is part of GnuTLS.
5  *
6  * GnuTLS is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuTLS is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GnuTLS; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #if defined(_WIN32)
30
31 int main()
32 {
33         exit(77);
34 }
35
36 #else
37
38 # include <sys/types.h>
39 # include <netinet/in.h>
40 # include <sys/socket.h>
41 # include <sys/wait.h>
42 # include <arpa/inet.h>
43 # include <unistd.h>
44 # include <gnutls/gnutls.h>
45 # include <gnutls/dtls.h>
46 # include <signal.h>
47
48 # ifndef MSG_NOSIGNAL
49
50 int main()
51 {
52         exit(77);
53 }
54
55 # else
56
57 # include "utils.h"
58
59 static
60 void sigpipe(int sig)
61 {
62         fail("sigpipe received\n");
63         exit(1);
64 }
65
66 #define BUF_SIZE 64
67
68 static void client(int fd)
69 {
70         int ret;
71         gnutls_anon_client_credentials_t anoncred;
72         gnutls_session_t session;
73         char buf[BUF_SIZE];
74         char buf2[BUF_SIZE];
75         /* Need to enable anonymous KX specifically. */
76
77         global_init();
78
79         if (debug) {
80                 gnutls_global_set_log_level(4711);
81         }
82
83         gnutls_anon_allocate_client_credentials(&anoncred);
84
85         /* Initialize TLS session
86          */
87         gnutls_init(&session, GNUTLS_CLIENT);
88         gnutls_handshake_set_timeout(session, 20 * 1000);
89
90         /* Use default priorities */
91         gnutls_priority_set_direct(session,
92                                    "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
93                                    NULL);
94
95         /* put the anonymous credentials to the current session
96          */
97         gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
98
99         gnutls_transport_set_int(session, fd);
100
101         /* Perform the TLS handshake
102          */
103         do {
104                 ret = gnutls_handshake(session);
105         }
106         while (ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
107
108         ret = gnutls_record_recv(session, buf, sizeof(buf));
109         if (ret < 0 || ret != sizeof(buf)) {
110                 kill(getppid(), SIGPIPE);
111                 fail("client: recv failed");
112         }
113         if (debug)
114                 success("client: received %d bytes\n", ret);
115
116         memset(buf2, 0, sizeof(buf));
117         if (memcmp(buf, buf2, sizeof(buf)) != 0) {
118                 kill(getppid(), SIGPIPE);
119                 fail("client: recv data failed");
120         }
121
122         close(fd);
123         gnutls_deinit(session);
124         gnutls_anon_free_client_credentials(anoncred);
125         gnutls_global_deinit();
126
127         if (ret < 0) {
128                 fail("client: Handshake failed with unexpected reason: %s\n", gnutls_strerror(ret));
129         } else {
130                 if (debug)
131                         success("client: Handshake was completed\n");
132         }
133 }
134
135
136 /* These are global */
137 pid_t child;
138
139 static void server(int fd)
140 {
141         gnutls_anon_server_credentials_t anoncred;
142         gnutls_session_t session;
143         int ret;
144         char buf[BUF_SIZE];
145         unsigned i;
146         /* this must be called once in the program
147          */
148         global_init();
149
150         if (debug) {
151                 gnutls_global_set_log_level(4711);
152         }
153
154         gnutls_anon_allocate_server_credentials(&anoncred);
155
156         gnutls_init(&session, GNUTLS_SERVER|GNUTLS_NO_SIGNAL);
157
158         /* avoid calling all the priority functions, since the defaults
159          * are adequate.
160          */
161         gnutls_priority_set_direct(session,
162                                    "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL",
163                                    NULL);
164
165         gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred);
166
167         gnutls_transport_set_int(session, fd);
168
169         do {
170                 ret = gnutls_handshake(session);
171         }
172         while (ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
173
174         if (ret < 0) {
175                 fail("error in handshake: %s\n", gnutls_strerror(ret));
176                 exit(1);
177         }
178
179         memset(buf, 0, sizeof(buf));
180         for (i=0;i<5;i++) {
181                 sleep(3);
182                 ret = gnutls_record_send(session, buf, sizeof(buf));
183                 if (ret < 0)
184                         break;
185         }
186
187         sleep(3);
188
189         gnutls_deinit(session);
190         gnutls_anon_free_server_credentials(anoncred);
191         gnutls_global_deinit();
192
193 }
194
195 static void start(void)
196 {
197         int fd[2];
198         int ret;
199
200         /* we need dgram in this test */
201         ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
202         if (ret < 0) {
203                 perror("socketpair");
204                 exit(1);
205         }
206
207         child = fork();
208         if (child < 0) {
209                 perror("fork");
210                 fail("fork");
211                 exit(1);
212         }
213
214         if (child) {
215                 /* parent */
216                 close(fd[0]);
217                 server(fd[1]);
218                 close(fd[1]);
219                 kill(child, SIGTERM);
220         } else {
221                 close(fd[1]);
222                 client(fd[0]);
223                 close(fd[0]);
224                 exit(0);
225         }
226 }
227
228 static void ch_handler(int sig)
229 {
230         int status = 0;
231         wait(&status);
232         if (WEXITSTATUS(status) != 0)
233                 fail("Child died with status %d\n", WEXITSTATUS(status));
234         return;
235 }
236
237 void doit(void)
238 {
239         signal(SIGCHLD, ch_handler);
240         signal(SIGPIPE, sigpipe);
241
242         start();
243 }
244
245 # endif /* MSG_NOSIGNAL */
246 #endif                          /* _WIN32 */