]>
git.saurik.com Git - apple/security.git/blob - Security/tlsnke/tlsnketest/main.c
2 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
33 #include <net/kext_net.h>
40 #include <AssertMacros.h>
41 #include "tlssocket.h"
45 static void print_data(const char *s
, size_t l
, const unsigned char *p
)
47 printf("%s, %zu:",s
, l
);
48 for(int i
=0; i
<l
; i
++)
49 printf(" %02x", p
[i
]);
53 static void *server_thread_func(void *arg
)
56 struct sockaddr_in server_addr
;
59 if ((sock
= socket(AF_INET
, SOCK_DGRAM
, 0)) == -1) {
60 perror("server socket");
64 // Dont use TLSSocket_Attach for the server:
65 // TLSSocket_Attach can only open one TLS socket at a time.
67 struct so_nke so_tlsnke
;
69 memset(&so_tlsnke
, 0, sizeof(so_tlsnke
));
70 so_tlsnke
.nke_handle
= TLS_HANDLE_IP4
;
71 err
=setsockopt(sock
, SOL_SOCKET
, SO_NKE
, &so_tlsnke
, sizeof(so_tlsnke
));
73 perror("attach (server)");
78 server_addr
.sin_family
= AF_INET
;
79 server_addr
.sin_port
= htons(23232);
80 server_addr
.sin_addr
.s_addr
= INADDR_ANY
;
81 bzero(&(server_addr
.sin_zero
),8);
83 if (bind(sock
, (struct sockaddr
*)&server_addr
, sizeof(struct sockaddr
))
85 perror("Unable to bind");
89 printf("\nBound - Server Waiting for client on port 23232\n");
96 rc
=TLSSocket_Funcs
.read((intptr_t)sock
, &rec
);
98 print_data("recvd", rec
.contents
.length
, rec
.contents
.data
);
99 rec
.contents
.data
[rec
.contents
.length
-1]=0;
100 printf("recvd: %ld, %s\n", rec
.contents
.length
, rec
.contents
.data
);
101 free(rec
.contents
.data
);
103 printf("read failed: %d\n", rc
);
111 static int create_client_socket(const char *hostname
)
117 printf("Create client socket\n");
118 sock
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
120 perror("client socket");
126 err
=TLSSocket_Attach(sock
);
128 perror("TLSSocket_Attach (server)");
134 struct hostent
*host
;
135 struct sockaddr_in server_addr
;
137 //host = gethostbyname("kruk.apple.com");
138 //host = gethostbyname("localhost");
139 host
= gethostbyname(hostname
);
144 server_addr
.sin_family
= AF_INET
;
145 server_addr
.sin_port
= htons(23232);
146 server_addr
.sin_addr
= *((struct in_addr
*)host
->h_addr
);
147 bzero(&(server_addr
.sin_zero
),8);
149 err
= connect(sock
, (struct sockaddr
*)&server_addr
,
150 sizeof(struct sockaddr
));
161 static int kext_test(const char *hostname
, int bypass
)
164 char send_data
[1024];
166 pthread_t server_thread
;
168 if(strcmp(hostname
, "localhost")==0) {
169 pthread_create(&server_thread
, NULL
, server_thread_func
, NULL
);
170 // Just wait for the server to be setup
175 sock
= create_client_socket(hostname
);
178 /* Have to open this after we attached the filter to the client socket */
179 tlsfd
=open("/dev/tlsnke", O_RDWR
);
181 perror("open tlsnke");
190 n
=sprintf(send_data
, "Message #%d\n", i
);
196 printf("Client(1) sending %d bytes (\"%s\")\n", n
, send_data
);
199 err
= write(tlsfd
, send_data
, n
);
201 perror("write to tlsnke");
207 rec
.contentType
= SSL_RecordTypeAppData
;
208 rec
.protocolVersion
= DTLS_Version_1_0
;
209 rec
.contents
.data
= (uint8_t *)send_data
;
210 rec
.contents
.length
= n
;
212 err
= TLSSocket_Funcs
.write((intptr_t)sock
, rec
);
214 perror("write to socket");
218 /* serviceWriteQueue every 2 writes, this will trigger rdar://11348395 */
221 err
= TLSSocket_Funcs
.serviceWriteQueue((intptr_t)sock
);
223 perror("service write queue");
240 int dtls_client(const char *hostname
, int bypass
);
243 int usage(const char *argv0
)
245 printf("Usage: %s <test> <hostname> <bypass>\n", argv0
);
246 printf(" <test>: type of test: 's'imple, 'h'andshake or 'e'cho] (see below)\n");
247 printf(" <hostname>: hostname of server\n");
248 printf(" <bypass>: use /dev/tlsnke bypass test\n");
250 printf("\n 'S'imple test:\n"
251 "\tVery basic test with no handshake. DTLS packets are sent through the socket filter, non encrypted.\n"
252 "\tIf hostname is 'localhost', a local simple server will be created that will also use the tls filter,\n"
253 "\tsuch that the input path is tested.\n"
254 "\tOtherwise, a server on the other side is not required only the output path is tested. If there is no server replying\n"
255 "\tonly the ouput path will be tested. If a server is replying, input packet will be processed but are never read to userspace\n"
256 "\tif bypass=1, also send the same packet through the /dev/tlsnke interface, as if they were coming from utun\n");
258 printf("\n 'H'andshake:\n");
259 printf("\tTest SSL Handshake with various ciphers, between a local client going through the tlsnke\n"
260 "\tfilter, and a local server using only the userland SecureTransport.\n"
261 "\thostname and bypass are ignored.\n");
263 printf("\n 'E'cho:\n");
264 printf("\tTest to connect to an udp echo server indicated by hostname, on port 23232.\n"
265 "\tSet bypass=1 to use the /dev/tlsnke bsd device to send/recv the app data (emulate utun behaviour)\n");
267 printf("\n\tbypass=1 require the tlsnke kext to be compiled with TLS_TEST=1 (not the default in the build)\n");
272 int main (int argc
, const char * argv
[])
275 printf("argv0=%s argc=%d\n", argv
[0], argc
);
277 return usage(argv
[0]);
279 switch (argv
[1][0]) {
282 if(argc
<3) return usage(argv
[0]);
283 return kext_test(argv
[2], atoi(argv
[3])?1:0);
289 if(argc
<3) return usage(argv
[0]);
290 return dtls_client(argv
[2], atoi(argv
[3])?1:0);
292 return usage(argv
[0]);