blob: f2f56f835808a1dad0b78d584d9c5dc98a0fd39c [file] [log] [blame]
James E. King, III36628a22017-02-13 15:25:41 -05001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
James E. King, III36628a22017-02-13 15:25:41 -050020#include <netdb.h>
21#include <sys/wait.h>
22#include <sys/types.h>
23#include <sys/socket.h>
24#include <netdb.h>
25#include <arpa/inet.h>
26
27#include <thrift/c_glib/transport/thrift_transport.h>
28#include <thrift/c_glib/transport/thrift_buffered_transport.h>
29#include <thrift/c_glib/transport/thrift_server_transport.h>
30#include <thrift/c_glib/transport/thrift_server_socket.h>
31#include <thrift/c_glib/transport/thrift_ssl_socket.h>
32
33//#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }
34#define TEST_DATA { "GET / HTTP/1.1\n\n" }
35
36
37/* substituted functions to test failures of system and library calls */
38static int socket_error = 0;
39int
40my_socket(int domain, int type, int protocol)
41{
James E. King, III43f4bf22017-10-28 12:54:02 -040042 if (socket_error == 0)
43 {
44 return socket (domain, type, protocol);
45 }
46 return -1;
James E. King, III36628a22017-02-13 15:25:41 -050047}
48
49static int recv_error = 0;
50ssize_t
51my_recv(int socket, void *buffer, size_t length, int flags)
52{
James E. King, III43f4bf22017-10-28 12:54:02 -040053 if (recv_error == 0)
54 {
55 return recv (socket, buffer, length, flags);
56 }
57 return -1;
James E. King, III36628a22017-02-13 15:25:41 -050058}
59
60static int send_error = 0;
61ssize_t
62my_send(int socket, const void *buffer, size_t length, int flags)
63{
James E. King, III43f4bf22017-10-28 12:54:02 -040064 if (send_error == 0)
65 {
66 return send (socket, buffer, length, flags);
67 }
68 return -1;
James E. King, III36628a22017-02-13 15:25:41 -050069}
70
71#define socket my_socket
72#define recv my_recv
73#define send my_send
74#include "../src/thrift/c_glib/transport/thrift_ssl_socket.c"
75#undef socket
76#undef recv
77#undef send
78
79static void thrift_ssl_socket_server (const int port);
80
81/* test object creation and destruction */
82static void
83test_ssl_create_and_destroy(void)
84{
James E. King, III43f4bf22017-10-28 12:54:02 -040085 gchar *hostname = NULL;
86 guint port = 0;
James E. King, III36628a22017-02-13 15:25:41 -050087
James E. King, III43f4bf22017-10-28 12:54:02 -040088 GObject *object = NULL;
89 object = g_object_new (THRIFT_TYPE_SSL_SOCKET, NULL);
90 g_assert (object != NULL);
91 g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL);
92 g_free (hostname);
93 g_object_unref (object);
James E. King, III36628a22017-02-13 15:25:41 -050094}
95
96static void
97test_ssl_create_and_set_properties(void)
98{
James E. King, III43f4bf22017-10-28 12:54:02 -040099 gchar *hostname = NULL;
100 guint port = 0;
101 SSL_CTX* ssl_ctx= NULL;
102 GError *error=NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500103
James E. King, III43f4bf22017-10-28 12:54:02 -0400104 GObject *object = NULL;
105 object = thrift_ssl_socket_new(SSLTLS, &error);
106 g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, "ssl_context", &ssl_ctx, NULL);
107 g_assert (ssl_ctx!=NULL);
James E. King, III36628a22017-02-13 15:25:41 -0500108
James E. King, III43f4bf22017-10-28 12:54:02 -0400109 g_free (hostname);
110 g_object_unref (object);
James E. King, III36628a22017-02-13 15:25:41 -0500111}
112
113static void
114test_ssl_open_and_close(void)
115{
James E. King, III43f4bf22017-10-28 12:54:02 -0400116 ThriftSSLSocket *tSSLSocket = NULL;
117 ThriftTransport *transport = NULL;
118 GError *error=NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500119
James E. King, III43f4bf22017-10-28 12:54:02 -0400120 /* open a connection and close it */
121 tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error);
James E. King, III36628a22017-02-13 15:25:41 -0500122
James E. King, III43f4bf22017-10-28 12:54:02 -0400123 transport = THRIFT_TRANSPORT (tSSLSocket);
124 thrift_ssl_socket_open (transport, NULL);
125 g_assert (thrift_ssl_socket_is_open (transport) == TRUE);
126 thrift_ssl_socket_close (transport, NULL);
127 g_assert (thrift_ssl_socket_is_open (transport) == FALSE);
James E. King, III36628a22017-02-13 15:25:41 -0500128
James E. King, III43f4bf22017-10-28 12:54:02 -0400129 /* test close failure */
130 THRIFT_SOCKET(tSSLSocket)->sd = -1;
131 thrift_ssl_socket_close (transport, NULL);
132 g_object_unref (tSSLSocket);
James E. King, III36628a22017-02-13 15:25:41 -0500133
James E. King, III43f4bf22017-10-28 12:54:02 -0400134 /* try a hostname lookup failure */
135 tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", 51188, &error);
136 transport = THRIFT_TRANSPORT (tSSLSocket);
137 g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
138 g_object_unref (tSSLSocket);
139 g_error_free (error);
140 error = NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500141
James E. King, III43f4bf22017-10-28 12:54:02 -0400142 /* try an error call to socket() */
143 tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error);
144 transport = THRIFT_TRANSPORT (tSSLSocket);
145 socket_error = 1;
146 g_assert (thrift_ssl_socket_open (transport, &error) == FALSE);
147 socket_error = 0;
148 g_object_unref (tSSLSocket);
149 g_error_free (error);
James E. King, III36628a22017-02-13 15:25:41 -0500150}
151
152
153
154/**
155 * Print the common name of certificate
156 */
157unsigned char * get_cn_name(X509_NAME* const name)
158{
James E. King, III43f4bf22017-10-28 12:54:02 -0400159 int idx = -1;
160 unsigned char *utf8 = NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500161
James E. King, III43f4bf22017-10-28 12:54:02 -0400162 do
163 {
164 if(!name) break; /* failed */
James E. King, III36628a22017-02-13 15:25:41 -0500165
James E. King, III43f4bf22017-10-28 12:54:02 -0400166 idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
167 if(!(idx > -1)) break; /* failed */
James E. King, III36628a22017-02-13 15:25:41 -0500168
James E. King, III43f4bf22017-10-28 12:54:02 -0400169 X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx);
170 if(!entry) break; /* failed */
James E. King, III36628a22017-02-13 15:25:41 -0500171
James E. King, III43f4bf22017-10-28 12:54:02 -0400172 ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry);
173 if(!data) break; /* failed */
James E. King, III36628a22017-02-13 15:25:41 -0500174
James E. King, III43f4bf22017-10-28 12:54:02 -0400175 int length = ASN1_STRING_to_UTF8(&utf8, data);
176 if(!utf8 || !(length > 0)) break; /* failed */
James E. King, III36628a22017-02-13 15:25:41 -0500177
James E. King, III43f4bf22017-10-28 12:54:02 -0400178 } while (0);
179 return utf8;
James E. King, III36628a22017-02-13 15:25:41 -0500180}
181
182/*
183 * Handle IPV4 and IPV6 addr
184 */
185void *get_in_addr(struct sockaddr *sa)
186{
James E. King, III43f4bf22017-10-28 12:54:02 -0400187 if (sa->sa_family == AF_INET)
188 return &(((struct sockaddr_in*)sa)->sin_addr);
189 return &(((struct sockaddr_in6*)sa)->sin6_addr);
James E. King, III36628a22017-02-13 15:25:41 -0500190}
191
192int verify_ip(char * hostname, struct sockaddr_storage *addr)
193{
James E. King, III43f4bf22017-10-28 12:54:02 -0400194 struct addrinfo *addr_info,*p;
195 struct addrinfo hints;
196 int res;
197 int retval = 0;
James E. King, III36628a22017-02-13 15:25:41 -0500198
199
James E. King, III43f4bf22017-10-28 12:54:02 -0400200 memset(&hints, 0, sizeof hints);
201 hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
202 hints.ai_socktype = SOCK_STREAM;
James E. King, III36628a22017-02-13 15:25:41 -0500203
204
James E. King, III43f4bf22017-10-28 12:54:02 -0400205 if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0)
206 {
207 // get the host info
208 g_error("Cannot get the host address");
209 return retval;
210 }
211 // loop through all the results and connect to the first we can
212 char dnshost[INET6_ADDRSTRLEN]; // bigger addr supported IPV6
213 char socket_ip[INET6_ADDRSTRLEN];
214 if(inet_ntop(addr->ss_family, get_in_addr(addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){
215 g_debug("We are connected to host %s checking against certificate...", socket_ip);
216 int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0;
217 for(p = addr_info; p != NULL; p = p->ai_next) {
218 if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){
219 if(dnshost!=NULL){
220 g_info("DNS address [%i -> %s]", p->ai_addr, dnshost);
221 if(!strncmp(dnshost, socket_ip, sizeip)){
222 retval=1;
223 break; // if we get here, we must have connected successfully
224 }
225 }
226 }
227 }
228 }
James E. King, III36628a22017-02-13 15:25:41 -0500229
James E. King, III43f4bf22017-10-28 12:54:02 -0400230 if(addr_info)
231 freeaddrinfo(addr_info);
James E. King, III36628a22017-02-13 15:25:41 -0500232
James E. King, III43f4bf22017-10-28 12:54:02 -0400233 return retval;
James E. King, III36628a22017-02-13 15:25:41 -0500234}
235
236static void
237read_from_file(char *buffer, long size, const char *file_name)
238{
James E. King, III43f4bf22017-10-28 12:54:02 -0400239 char ch;
240 long index=0;
241 FILE *fp;
James E. King, III36628a22017-02-13 15:25:41 -0500242
James E. King, III43f4bf22017-10-28 12:54:02 -0400243 fp = fopen(file_name,"r"); // read mode
James E. King, III36628a22017-02-13 15:25:41 -0500244
James E. King, III43f4bf22017-10-28 12:54:02 -0400245 if( fp == NULL )
246 {
247 perror("Error while opening the file.\n");
248 exit(EXIT_FAILURE);
249 }
James E. King, III36628a22017-02-13 15:25:41 -0500250
James E. King, III43f4bf22017-10-28 12:54:02 -0400251 printf("The contents of %s file are :\n", file_name);
James E. King, III36628a22017-02-13 15:25:41 -0500252
James E. King, III43f4bf22017-10-28 12:54:02 -0400253 while(index<size && ( ch = fgetc(fp) ) != EOF ){
254 buffer[index++] = ch;
255 }
James E. King, III36628a22017-02-13 15:25:41 -0500256
James E. King, III43f4bf22017-10-28 12:54:02 -0400257 fclose(fp);
James E. King, III36628a22017-02-13 15:25:41 -0500258}
259
260#define ISSUER_CN_PINNING "The Apache Software Foundation"
261#define SUBJECT_CN_PINNING "localhost"
262#define CERT_SERIAL_NUMBER "1"
263
264gboolean verify_certificate_sn(X509 *cert, const unsigned char *serial_number)
265{
James E. King, III43f4bf22017-10-28 12:54:02 -0400266 gboolean retval = FALSE;
James E. King, III36628a22017-02-13 15:25:41 -0500267
James E. King, III43f4bf22017-10-28 12:54:02 -0400268 ASN1_INTEGER *serial = X509_get_serialNumber(cert);
James E. King, III36628a22017-02-13 15:25:41 -0500269
James E. King, III43f4bf22017-10-28 12:54:02 -0400270 BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL);
271 if (!bn) {
272 fprintf(stderr, "unable to convert ASN1INTEGER to BN\n");
273 return EXIT_FAILURE;
274 }
275 char *tmp = BN_bn2dec(bn);
276 if (!tmp) {
277 g_warning(stderr, "unable to convert BN to decimal string.\n");
278 BN_free(bn);
279 return EXIT_FAILURE;
280 }
281// if (strlen(tmp) >= len) {
282// g_warn(stderr, "buffer length shorter than serial number\n");
283// BN_free(bn);
284// OPENSSL_free(tmp);
285// return EXIT_FAILURE;
286// }
287 if(!strncmp(serial_number, tmp, strlen(serial_number))){
288 retval=TRUE;
289 }else{
290 g_warning("Serial number is not valid");
291 }
James E. King, III36628a22017-02-13 15:25:41 -0500292
James E. King, III43f4bf22017-10-28 12:54:02 -0400293 BN_free(bn);
294 OPENSSL_free(tmp);
295 return retval;
James E. King, III36628a22017-02-13 15:25:41 -0500296}
297
298gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error)
299{
James E. King, III43f4bf22017-10-28 12:54:02 -0400300 ThriftSSLSocket *sslSocket = THRIFT_SSL_SOCKET (transport);
James E. King, III36628a22017-02-13 15:25:41 -0500301
James E. King, III43f4bf22017-10-28 12:54:02 -0400302 g_info("Processing access to the server");
303 X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL;
304 X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500305
James E. King, III43f4bf22017-10-28 12:54:02 -0400306 /* Issuer is the authority we trust that warrants nothing useful */
307 const unsigned char * issuer = get_cn_name(iname);
308 if(issuer){
309 gboolean valid = TRUE;
310 g_info("Issuer (cn) %s", issuer);
James E. King, III36628a22017-02-13 15:25:41 -0500311
James E. King, III43f4bf22017-10-28 12:54:02 -0400312 // Issuer pinning
313 if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){
314 g_warning("The Issuer of the certificate is not valid");
315 valid=FALSE;
316 }
317 OPENSSL_free(issuer);
318 if(!valid)
319 return valid;
320 }
James E. King, III36628a22017-02-13 15:25:41 -0500321
322
James E. King, III43f4bf22017-10-28 12:54:02 -0400323 /* Subject is who the certificate is issued to by the authority */
324 const unsigned char * subject = get_cn_name(sname);
325 if(subject){
326 g_info("Subject (cn) %s", subject);
327 gboolean valid = TRUE;
James E. King, III36628a22017-02-13 15:25:41 -0500328
James E. King, III43f4bf22017-10-28 12:54:02 -0400329 // Subject pinning
330 if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){
331 g_warning("The subject of the certificate is not valid");
332 valid=FALSE;
333 }
James E. King, III36628a22017-02-13 15:25:41 -0500334
James E. King, III43f4bf22017-10-28 12:54:02 -0400335 if(!valid)
336 return valid;
James E. King, III36628a22017-02-13 15:25:41 -0500337
James E. King, III43f4bf22017-10-28 12:54:02 -0400338 // Host pinning
339 if(verify_ip(subject, addr)){
340 g_info("Verified subject");
341 }else{
342 g_info("Cannot verify subject");
343 valid=FALSE;
344 }
345 OPENSSL_free(subject);
James E. King, III36628a22017-02-13 15:25:41 -0500346
James E. King, III43f4bf22017-10-28 12:54:02 -0400347 if(!valid)
348 return valid;
349 }
James E. King, III36628a22017-02-13 15:25:41 -0500350
James E. King, III43f4bf22017-10-28 12:54:02 -0400351 if(!verify_certificate_sn(cert, CERT_SERIAL_NUMBER)){
352 return FALSE;
353 }else{
354 g_info("Verified serial number");
355 }
James E. King, III36628a22017-02-13 15:25:41 -0500356
James E. King, III43f4bf22017-10-28 12:54:02 -0400357 return TRUE;
James E. King, III36628a22017-02-13 15:25:41 -0500358
359}
360
361
362
363
364#ifdef BUILD_SERVER
365static void
366test_ssl_authorization_manager(void)
367{
James E. King, III43f4bf22017-10-28 12:54:02 -0400368 int status=0;
369 pid_t pid;
370 ThriftSSLSocket *tSSLsocket = NULL;
371 ThriftTransport *transport = NULL;
372 // int port = 51199;
373 int port = 443;
374 GError *error=NULL;
James E. King, III36628a22017-02-13 15:25:41 -0500375
James E. King, III43f4bf22017-10-28 12:54:02 -0400376 guchar buf[17] = TEST_DATA; /* a buffer */
James E. King, III36628a22017-02-13 15:25:41 -0500377
James E. King, III43f4bf22017-10-28 12:54:02 -0400378 // pid = fork ();
379 // g_assert ( pid >= 0 );
380 //
381 // if ( pid == 0 )
382 // {
383 // /* child listens */
384 // thrift_ssl_socket_server (port);
385 // exit (0);
386 // } else {
387 /* parent connects, wait a bit for the socket to be created */
388 sleep (1);
James E. King, III36628a22017-02-13 15:25:41 -0500389
James E. King, III43f4bf22017-10-28 12:54:02 -0400390 // Test against level2 owncloud certificate
391 tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error);
392 thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); // Install pinning manager
393 //thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem");
394 unsigned char cert_buffer[65534];
395 read_from_file(cert_buffer, 65534, "../../keys/client.pem");
396 if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){
397 g_warning("Certificates cannot be loaded!");
398 }
James E. King, III36628a22017-02-13 15:25:41 -0500399
James E. King, III43f4bf22017-10-28 12:54:02 -0400400 transport = THRIFT_TRANSPORT (tSSLsocket);
401 g_assert (thrift_ssl_socket_open (transport, NULL) == TRUE);
402 g_assert (thrift_ssl_socket_is_open (transport));
James E. King, III36628a22017-02-13 15:25:41 -0500403
James E. King, III43f4bf22017-10-28 12:54:02 -0400404 thrift_ssl_socket_write (transport, buf, 17, NULL);
James E. King, III36628a22017-02-13 15:25:41 -0500405
James E. King, III43f4bf22017-10-28 12:54:02 -0400406 /* write fail */
407 send_error = 1;
408 // thrift_ssl_socket_write (transport, buf, 1, NULL);
409 // send_error = 0;
James E. King, III36628a22017-02-13 15:25:41 -0500410
James E. King, III43f4bf22017-10-28 12:54:02 -0400411 // thrift_ssl_socket_write_end (transport, NULL);
412 // thrift_ssl_socket_flush (transport, NULL);
413 thrift_ssl_socket_close (transport, NULL);
414 g_object_unref (tSSLsocket);
James E. King, III36628a22017-02-13 15:25:41 -0500415
James E. King, III43f4bf22017-10-28 12:54:02 -0400416 // g_assert ( wait (&status) == pid );
417 g_assert ( status == 0 );
418 // }
James E. King, III36628a22017-02-13 15:25:41 -0500419}
420#endif
421
422
423/* test ThriftSocket's peek() implementation */
424//static void
425//test_ssl_peek(void)
426//{
427// gint status;
428// pid_t pid;
429// guint port = 51199;
430// gchar data = 'A';
431// ThriftTransport *client_transport;
432// GError *error = NULL;
433//
434// client_transport = g_object_new (THRIFT_TYPE_SSL_SOCKET,
435// "hostname", "localhost",
436// "port", port,
437// NULL);
438//
439// /* thrift_transport_peek returns FALSE when the socket is closed */
440// g_assert (thrift_transport_is_open (client_transport) == FALSE);
441// g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
442// g_assert (error == NULL);
443//
444// pid = fork ();
445// g_assert (pid >= 0);
446//
447// if (pid == 0)
448// {
449// ThriftServerTransport *server_transport = NULL;
450//
451// g_object_unref (client_transport);
452//
453// /* child listens */
454// server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
455// "port", port,
456// NULL);
457// g_assert (server_transport != NULL);
458//
459// thrift_server_transport_listen (server_transport, &error);
460// g_assert (error == NULL);
461//
462// client_transport = g_object_new
463// (THRIFT_TYPE_BUFFERED_TRANSPORT,
464// "transport", thrift_server_transport_accept (server_transport, &error),
465// "r_buf_size", 0,
466// "w_buf_size", sizeof data,
467// NULL);
468// g_assert (error == NULL);
469// g_assert (client_transport != NULL);
470//
471// /* write exactly one character to the client */
472// g_assert (thrift_transport_write (client_transport,
473// &data,
474// sizeof data,
475// &error) == TRUE);
476//
477// thrift_transport_flush (client_transport, &error);
478// thrift_transport_write_end (client_transport, &error);
479// thrift_transport_close (client_transport, &error);
480//
481// g_object_unref (client_transport);
482// g_object_unref (server_transport);
483//
484// exit (0);
485// }
486// else {
487// /* parent connects, wait a bit for the socket to be created */
488// sleep (1);
489//
490// /* connect to the child */
491// thrift_transport_open (client_transport, &error);
492// g_assert (error == NULL);
493// g_assert (thrift_transport_is_open (client_transport) == TRUE);
494//
495// /* thrift_transport_peek returns TRUE when the socket is open and there is
496// data available to be read */
497// g_assert (thrift_transport_peek (client_transport, &error) == TRUE);
498// g_assert (error == NULL);
499//
500// /* read exactly one character from the server */
501// g_assert_cmpint (thrift_transport_read (client_transport,
502// &data,
503// sizeof data,
504// &error), ==, sizeof data);
505//
506// /* thrift_transport_peek returns FALSE when the socket is open but there is
507// no (more) data available to be read */
508// g_assert (thrift_transport_is_open (client_transport) == TRUE);
509// g_assert (thrift_transport_peek (client_transport, &error) == FALSE);
510// g_assert (error == NULL);
511//
512// thrift_transport_read_end (client_transport, &error);
513// thrift_transport_close (client_transport, &error);
514//
515// g_object_unref (client_transport);
516//
517// g_assert (wait (&status) == pid);
518// g_assert (status == 0);
519// }
520//}
521
522static void
523thrift_ssl_socket_server (const int port)
524{
James E. King, III43f4bf22017-10-28 12:54:02 -0400525 int bytes = 0;
526 ThriftServerTransport *transport = NULL;
527 ThriftTransport *client = NULL;
528 guchar buf[10]; /* a buffer */
529 guchar match[10] = TEST_DATA;
James E. King, III36628a22017-02-13 15:25:41 -0500530
James E. King, III43f4bf22017-10-28 12:54:02 -0400531 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
532 "port", port, NULL);
James E. King, III36628a22017-02-13 15:25:41 -0500533
James E. King, III43f4bf22017-10-28 12:54:02 -0400534 transport = THRIFT_SERVER_TRANSPORT (tsocket);
535 thrift_server_transport_listen (transport, NULL);
536 client = thrift_server_transport_accept (transport, NULL);
537 g_assert (client != NULL);
James E. King, III36628a22017-02-13 15:25:41 -0500538
James E. King, III43f4bf22017-10-28 12:54:02 -0400539 /* read 10 bytes */
540 bytes = thrift_ssl_socket_read (client, buf, 10, NULL);
541 g_assert (bytes == 10); /* make sure we've read 10 bytes */
542 g_assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */
James E. King, III36628a22017-02-13 15:25:41 -0500543
James E. King, III43f4bf22017-10-28 12:54:02 -0400544 /* failed read */
545 recv_error = 1;
546 thrift_ssl_socket_read (client, buf, 1, NULL);
547 recv_error = 0;
James E. King, III36628a22017-02-13 15:25:41 -0500548
James E. King, III43f4bf22017-10-28 12:54:02 -0400549 thrift_ssl_socket_read_end (client, NULL);
550 thrift_ssl_socket_close (client, NULL);
551 g_object_unref (tsocket);
552 g_object_unref (client);
James E. King, III36628a22017-02-13 15:25:41 -0500553}
554
555int
556main(int argc, char *argv[])
557{
James E. King, III43f4bf22017-10-28 12:54:02 -0400558 int retval;
James E. King, III36628a22017-02-13 15:25:41 -0500559#if (!GLIB_CHECK_VERSION (2, 36, 0))
James E. King, III43f4bf22017-10-28 12:54:02 -0400560 g_type_init();
James E. King, III36628a22017-02-13 15:25:41 -0500561#endif
562
James E. King, III43f4bf22017-10-28 12:54:02 -0400563 g_test_init (&argc, &argv, NULL);
James E. King, III36628a22017-02-13 15:25:41 -0500564
James E. King, III43f4bf22017-10-28 12:54:02 -0400565 thrift_ssl_socket_initialize_openssl();
James E. King, III36628a22017-02-13 15:25:41 -0500566
James E. King, III43f4bf22017-10-28 12:54:02 -0400567 g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy);
568 g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties);
569 g_test_add_func ("/testtransportsslsocket/OpenAndClose", test_ssl_open_and_close);
570 // This test is disabled because server is not ready
571 // g_test_add_func ("/testtransportsslsocket/AuthorizationManagerPinning", test_ssl_authorization_manager);
572 // g_test_add_func ("/testtransportsslsocket/Peek", test_ssl_peek);
James E. King, III36628a22017-02-13 15:25:41 -0500573
James E. King, III43f4bf22017-10-28 12:54:02 -0400574 retval = g_test_run ();
James E. King, III36628a22017-02-13 15:25:41 -0500575
James E. King, III43f4bf22017-10-28 12:54:02 -0400576 thrift_ssl_socket_finalize_openssl();
James E. King, III36628a22017-02-13 15:25:41 -0500577
James E. King, III43f4bf22017-10-28 12:54:02 -0400578 return retval;
James E. King, III36628a22017-02-13 15:25:41 -0500579}
580