~ubuntu-branches/ubuntu/wily/apparmor/wily

« back to all changes in this revision

Viewing changes to tests/regression/apparmor/tcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      Copyright (C) 2002-2005 Novell/SUSE
 
3
 *
 
4
 *      This program is free software; you can redistribute it and/or
 
5
 *      modify it under the terms of the GNU General Public License as
 
6
 *      published by the Free Software Foundation, version 2 of the
 
7
 *      License.
 
8
 */
 
9
 
 
10
/* Basic tcp networking test. */
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#include <unistd.h>
 
16
#include <errno.h>
 
17
#include <netinet/in.h>
 
18
#include <netinet/tcp.h>
 
19
#include <sys/select.h>
 
20
#include <sys/socket.h>
 
21
#include <sys/time.h>
 
22
#include <sys/types.h>
 
23
#include <sys/wait.h>
 
24
#include <arpa/inet.h>
 
25
#include <fcntl.h>
 
26
 
 
27
#define HOSTIP "127.0.0.1"
 
28
#define HOSTPORT 9876
 
29
#define BUFSIZE 4096
 
30
#define WAITLEN 1 /* number of seconds for select to wait */
 
31
#define DATASOURCE "/dev/urandom"
 
32
 
 
33
char data[BUFSIZE];
 
34
 
 
35
/* server_bind_address returns the socket filedescriptor */
 
36
int
 
37
server_bind_address (int port) {
 
38
        int sockfd;
 
39
        struct sockaddr_in serv_addr;
 
40
        int value = 1;
 
41
 
 
42
        /* create a socket */
 
43
        if ((sockfd = socket (PF_INET, SOCK_STREAM, 0)) < 0) {
 
44
                perror ("FAIL: Server: can't open stream socket");
 
45
                return -1;
 
46
        }       
 
47
 
 
48
        /* don't use SO_REUSEADDR in production code. */
 
49
        setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
 
50
 
 
51
        memset(&serv_addr, 0UL, sizeof(serv_addr));
 
52
        serv_addr.sin_family = AF_INET;
 
53
        inet_pton (AF_INET, HOSTIP, &serv_addr.sin_addr);
 
54
        serv_addr.sin_port = htons(port);
 
55
 
 
56
        if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) != 0) {
 
57
                perror("FAIL: Server: can't bind socket");
 
58
                close(sockfd);
 
59
                return -1;
 
60
        }       
 
61
        
 
62
        listen (sockfd, 1);
 
63
 
 
64
        return sockfd;
 
65
}
 
66
 
 
67
int my_select_read (int fd, int secs) {
 
68
        fd_set rfds;
 
69
        struct timeval tv;
 
70
        int retval;
 
71
 
 
72
        FD_ZERO(&rfds);
 
73
        FD_SET(fd, &rfds);
 
74
        tv.tv_sec = secs;
 
75
        tv.tv_usec = 0;
 
76
        retval = select (fd + 1, &rfds, NULL, NULL, &tv);
 
77
        if ((retval == -1) || !(FD_ISSET(fd, &rfds))) {
 
78
                return -1;
 
79
        }
 
80
 
 
81
        return 0;
 
82
}
 
83
 
 
84
int my_select_write (int fd, int secs) {
 
85
        fd_set wfds;
 
86
        struct timeval tv;
 
87
        int retval;
 
88
 
 
89
        FD_ZERO(&wfds);
 
90
        FD_SET(fd, &wfds);
 
91
        tv.tv_sec = secs;
 
92
        tv.tv_usec = 0;
 
93
        retval = select (fd + 1, NULL, &wfds, NULL, &tv);
 
94
        if ((retval == -1) || !(FD_ISSET(fd, &wfds))) {
 
95
                return -1;
 
96
        }
 
97
 
 
98
        return 0;
 
99
}
 
100
 
 
101
int
 
102
do_server (int sockfd) {
 
103
        int newsockfd = -1;
 
104
        socklen_t clilen;
 
105
        struct sockaddr_in cli_addr;
 
106
        int retval = 0, len;
 
107
        char buffer[BUFSIZE];
 
108
 
 
109
        /* socket should already have listen() called on it by now */
 
110
        retval = my_select_read (sockfd, WAITLEN);
 
111
        if (retval != 0) {
 
112
                perror ("FAIL: Server: select failed");
 
113
                goto out;
 
114
        }
 
115
 
 
116
        clilen = sizeof (cli_addr);
 
117
        newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
 
118
 
 
119
        if (newsockfd < 0) {
 
120
                perror ("FAIL: Server: can't accept socket");
 
121
                retval = errno;
 
122
                goto out;
 
123
        }       
 
124
 
 
125
        retval = my_select_read (newsockfd, WAITLEN);
 
126
        if (retval != 0) {
 
127
                perror ("FAIL: Server: select failed");
 
128
                goto out;
 
129
        }
 
130
 
 
131
        len = recv (newsockfd, buffer, sizeof(buffer), 0);
 
132
        if (len <= 0) {
 
133
                perror ("FAIL: Server: read failed");
 
134
                retval = errno;
 
135
                goto out;
 
136
        }
 
137
 
 
138
        /* verify data received from the client */
 
139
        if (memcmp((void *) buffer, (void *) data, sizeof(buffer)) != 0) {
 
140
                fprintf(stderr, "FAIL: Server: memory comparison failed\n");
 
141
                retval = -1;
 
142
                goto out;
 
143
        }
 
144
 
 
145
        /* send the data back to the client */
 
146
        if (send(newsockfd, data, sizeof(buffer), 0) < sizeof(buffer)) {
 
147
                perror("FAIL: Server: problem sending data");
 
148
                retval = errno;
 
149
                goto out;
 
150
        }       
 
151
 
 
152
out:
 
153
        if (newsockfd >= 0) { 
 
154
                close (newsockfd);
 
155
        }
 
156
        close (sockfd);
 
157
        return retval;
 
158
}
 
159
 
 
160
 
 
161
int
 
162
do_client (int port) {
 
163
        int sockfd;
 
164
        struct sockaddr_in serv_addr;
 
165
        int retval, len;
 
166
        char buffer[BUFSIZE];
 
167
        
 
168
        /* create a socket */
 
169
        if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
 
170
                perror("FAIL: Client: can't open stream socket");
 
171
                retval = errno;
 
172
                goto out;
 
173
        }       
 
174
 
 
175
        /* Set to non_block. */
 
176
        fcntl(sockfd, F_SETFL, O_NONBLOCK);
 
177
        //setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value));
 
178
 
 
179
        memset(&serv_addr, 0UL, sizeof(serv_addr));
 
180
        serv_addr.sin_family = AF_INET;
 
181
        inet_pton(AF_INET, HOSTIP, &serv_addr.sin_addr);
 
182
        serv_addr.sin_port = htons(port);
 
183
 
 
184
        if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) != 0) {
 
185
                if (errno != EINPROGRESS) {
 
186
                        perror("FAIL: Client: can't connect to socket");
 
187
                        retval = errno;
 
188
                        goto out;
 
189
                }
 
190
        }       
 
191
 
 
192
        retval = my_select_write (sockfd, WAITLEN);
 
193
        if (retval != 0) {
 
194
                perror ("FAIL: Client: select failed");
 
195
                goto out;
 
196
        }
 
197
 
 
198
        /* send the data to the server */
 
199
        if (send(sockfd, data, sizeof(buffer), 0) < sizeof(buffer)) {
 
200
                perror("FAIL: Client: problem sending data");
 
201
                retval = errno;
 
202
                goto out;
 
203
        }       
 
204
 
 
205
        retval = my_select_read (sockfd, WAITLEN);
 
206
        if (retval != 0) {
 
207
                perror ("FAIL: Client: select failed");
 
208
                goto out;
 
209
        }
 
210
 
 
211
        len = recv (sockfd, buffer, sizeof(buffer), 0);
 
212
        if (len <= 0) {
 
213
                perror ("FAIL: Client: read failed");
 
214
                retval = errno;
 
215
                goto out;
 
216
        }
 
217
 
 
218
        /* verify the data returned from the server */
 
219
        if (memcmp((void *) buffer, (void *) data, sizeof(buffer)) != 0) {
 
220
                fprintf(stderr, "FAIL: Client: memory comparison failed\n");
 
221
                retval = -1;
 
222
                goto out;
 
223
        }
 
224
 
 
225
        retval = 0;
 
226
out:
 
227
        if (sockfd >= 0) close(sockfd);
 
228
        return retval;
 
229
}
 
230
 
 
231
int 
 
232
main (int argc, char * argv[]) {
 
233
        pid_t childpid;
 
234
        int fd, retval, waitstatus;
 
235
        int sockfd = -1;
 
236
        int serv_port = HOSTPORT;
 
237
 
 
238
        fd = open(DATASOURCE, O_RDONLY);
 
239
        if (fd < 0) {
 
240
                perror("FAIL: open()ing data source failed");
 
241
                return errno;
 
242
        }
 
243
 
 
244
        if ((retval = read(fd, data, sizeof(data))) < sizeof(data)) {
 
245
                perror("FAIL: problem reading data source");
 
246
                close(fd);
 
247
                return errno;
 
248
        }
 
249
        close(fd);
 
250
 
 
251
        if (argc > 1) {
 
252
                serv_port = strtol(argv[1], NULL, 10);
 
253
        }
 
254
 
 
255
        /* get the server to listen, so the child has something to
 
256
         * connect to if it wins the race. */
 
257
        if ((sockfd = server_bind_address(serv_port)) < 0) {
 
258
                return errno;
 
259
        }
 
260
        
 
261
        if ((childpid = fork()) < 0) {
 
262
                perror("FAIL: fork() failed");
 
263
                return errno;
 
264
        }
 
265
 
 
266
        if (childpid == 0) {
 
267
                return do_client (serv_port);
 
268
        } else {
 
269
                do_server(sockfd);
 
270
        }
 
271
 
 
272
        wait(&waitstatus);
 
273
 
 
274
        if ((WIFEXITED(waitstatus) != 0) && (WEXITSTATUS(waitstatus) == 0)) {
 
275
                printf("PASS\n");
 
276
        }
 
277
 
 
278
        return 0;
 
279
}