James E. King, III | 36628a2 | 2017-02-13 15:25:41 -0500 | [diff] [blame^] | 1 | /* |
| 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 | |
| 20 | #include <assert.h> |
| 21 | #include <netdb.h> |
| 22 | #include <sys/wait.h> |
| 23 | #include <sys/types.h> |
| 24 | #include <sys/socket.h> |
| 25 | #include <netdb.h> |
| 26 | #include <arpa/inet.h> |
| 27 | |
| 28 | #include <thrift/c_glib/transport/thrift_transport.h> |
| 29 | #include <thrift/c_glib/transport/thrift_buffered_transport.h> |
| 30 | #include <thrift/c_glib/transport/thrift_server_transport.h> |
| 31 | #include <thrift/c_glib/transport/thrift_server_socket.h> |
| 32 | #include <thrift/c_glib/transport/thrift_ssl_socket.h> |
| 33 | |
| 34 | //#define TEST_DATA { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' } |
| 35 | #define TEST_DATA { "GET / HTTP/1.1\n\n" } |
| 36 | |
| 37 | |
| 38 | /* substituted functions to test failures of system and library calls */ |
| 39 | static int socket_error = 0; |
| 40 | int |
| 41 | my_socket(int domain, int type, int protocol) |
| 42 | { |
| 43 | if (socket_error == 0) |
| 44 | { |
| 45 | return socket (domain, type, protocol); |
| 46 | } |
| 47 | return -1; |
| 48 | } |
| 49 | |
| 50 | static int recv_error = 0; |
| 51 | ssize_t |
| 52 | my_recv(int socket, void *buffer, size_t length, int flags) |
| 53 | { |
| 54 | if (recv_error == 0) |
| 55 | { |
| 56 | return recv (socket, buffer, length, flags); |
| 57 | } |
| 58 | return -1; |
| 59 | } |
| 60 | |
| 61 | static int send_error = 0; |
| 62 | ssize_t |
| 63 | my_send(int socket, const void *buffer, size_t length, int flags) |
| 64 | { |
| 65 | if (send_error == 0) |
| 66 | { |
| 67 | return send (socket, buffer, length, flags); |
| 68 | } |
| 69 | return -1; |
| 70 | } |
| 71 | |
| 72 | #define socket my_socket |
| 73 | #define recv my_recv |
| 74 | #define send my_send |
| 75 | #include "../src/thrift/c_glib/transport/thrift_ssl_socket.c" |
| 76 | #undef socket |
| 77 | #undef recv |
| 78 | #undef send |
| 79 | |
| 80 | static void thrift_ssl_socket_server (const int port); |
| 81 | |
| 82 | /* test object creation and destruction */ |
| 83 | static void |
| 84 | test_ssl_create_and_destroy(void) |
| 85 | { |
| 86 | gchar *hostname = NULL; |
| 87 | guint port = 0; |
| 88 | |
| 89 | GObject *object = NULL; |
| 90 | object = g_object_new (THRIFT_TYPE_SSL_SOCKET, NULL); |
| 91 | assert (object != NULL); |
| 92 | g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, NULL); |
| 93 | g_free (hostname); |
| 94 | g_object_unref (object); |
| 95 | } |
| 96 | |
| 97 | static void |
| 98 | test_ssl_create_and_set_properties(void) |
| 99 | { |
| 100 | gchar *hostname = NULL; |
| 101 | guint port = 0; |
| 102 | SSL_CTX* ssl_ctx= NULL; |
| 103 | GError *error=NULL; |
| 104 | |
| 105 | GObject *object = NULL; |
| 106 | object = thrift_ssl_socket_new(SSLTLS, &error); |
| 107 | g_object_get (G_OBJECT(object), "hostname", &hostname, "port", &port, "ssl_context", &ssl_ctx, NULL); |
| 108 | assert (ssl_ctx!=NULL); |
| 109 | |
| 110 | g_free (hostname); |
| 111 | g_object_unref (object); |
| 112 | } |
| 113 | |
| 114 | static void |
| 115 | test_ssl_open_and_close(void) |
| 116 | { |
| 117 | ThriftSSLSocket *tSSLSocket = NULL; |
| 118 | ThriftTransport *transport = NULL; |
| 119 | GError *error=NULL; |
| 120 | |
| 121 | /* open a connection and close it */ |
| 122 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error); |
| 123 | |
| 124 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 125 | thrift_ssl_socket_open (transport, NULL); |
| 126 | assert (thrift_ssl_socket_is_open (transport) == TRUE); |
| 127 | thrift_ssl_socket_close (transport, NULL); |
| 128 | assert (thrift_ssl_socket_is_open (transport) == FALSE); |
| 129 | |
| 130 | /* test close failure */ |
| 131 | THRIFT_SOCKET(tSSLSocket)->sd = -1; |
| 132 | thrift_ssl_socket_close (transport, NULL); |
| 133 | g_object_unref (tSSLSocket); |
| 134 | |
| 135 | /* try a hostname lookup failure */ |
| 136 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost.broken", 51188, &error); |
| 137 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 138 | assert (thrift_ssl_socket_open (transport, &error) == FALSE); |
| 139 | g_object_unref (tSSLSocket); |
| 140 | g_error_free (error); |
| 141 | error = NULL; |
| 142 | |
| 143 | /* try an error call to socket() */ |
| 144 | tSSLSocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", 51188, &error); |
| 145 | transport = THRIFT_TRANSPORT (tSSLSocket); |
| 146 | socket_error = 1; |
| 147 | assert (thrift_ssl_socket_open (transport, &error) == FALSE); |
| 148 | socket_error = 0; |
| 149 | g_object_unref (tSSLSocket); |
| 150 | g_error_free (error); |
| 151 | } |
| 152 | |
| 153 | |
| 154 | |
| 155 | /** |
| 156 | * Print the common name of certificate |
| 157 | */ |
| 158 | unsigned char * get_cn_name(X509_NAME* const name) |
| 159 | { |
| 160 | int idx = -1; |
| 161 | unsigned char *utf8 = NULL; |
| 162 | |
| 163 | do |
| 164 | { |
| 165 | if(!name) break; /* failed */ |
| 166 | |
| 167 | idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1); |
| 168 | if(!(idx > -1)) break; /* failed */ |
| 169 | |
| 170 | X509_NAME_ENTRY* entry = X509_NAME_get_entry(name, idx); |
| 171 | if(!entry) break; /* failed */ |
| 172 | |
| 173 | ASN1_STRING* data = X509_NAME_ENTRY_get_data(entry); |
| 174 | if(!data) break; /* failed */ |
| 175 | |
| 176 | int length = ASN1_STRING_to_UTF8(&utf8, data); |
| 177 | if(!utf8 || !(length > 0)) break; /* failed */ |
| 178 | |
| 179 | } while (0); |
| 180 | return utf8; |
| 181 | } |
| 182 | |
| 183 | /* |
| 184 | * Handle IPV4 and IPV6 addr |
| 185 | */ |
| 186 | void *get_in_addr(struct sockaddr *sa) |
| 187 | { |
| 188 | if (sa->sa_family == AF_INET) |
| 189 | return &(((struct sockaddr_in*)sa)->sin_addr); |
| 190 | return &(((struct sockaddr_in6*)sa)->sin6_addr); |
| 191 | } |
| 192 | |
| 193 | int verify_ip(char * hostname, struct sockaddr_storage *addr) |
| 194 | { |
| 195 | struct addrinfo *addr_info,*p; |
| 196 | struct addrinfo hints; |
| 197 | int res; |
| 198 | int retval = 0; |
| 199 | |
| 200 | |
| 201 | memset(&hints, 0, sizeof hints); |
| 202 | hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6 |
| 203 | hints.ai_socktype = SOCK_STREAM; |
| 204 | |
| 205 | |
| 206 | if ( (res = getaddrinfo(hostname, NULL, &hints, &addr_info) ) != 0) |
| 207 | { |
| 208 | // get the host info |
| 209 | g_error("Cannot get the host address"); |
| 210 | return retval; |
| 211 | } |
| 212 | // loop through all the results and connect to the first we can |
| 213 | char dnshost[INET6_ADDRSTRLEN]; // bigger addr supported IPV6 |
| 214 | char socket_ip[INET6_ADDRSTRLEN]; |
| 215 | if(inet_ntop(addr->ss_family, get_in_addr(addr), socket_ip, INET6_ADDRSTRLEN)==socket_ip){ |
| 216 | g_debug("We are connected to host %s checking against certificate...", socket_ip); |
| 217 | int sizeip = socket_ip!=NULL ? strlen(socket_ip) : 0; |
| 218 | for(p = addr_info; p != NULL; p = p->ai_next) { |
| 219 | if(inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), dnshost, INET6_ADDRSTRLEN)==dnshost){ |
| 220 | if(dnshost!=NULL){ |
| 221 | g_info("DNS address [%i -> %s]", p->ai_addr, dnshost); |
| 222 | if(!strncmp(dnshost, socket_ip, sizeip)){ |
| 223 | retval=1; |
| 224 | break; // if we get here, we must have connected successfully |
| 225 | } |
| 226 | } |
| 227 | } |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | if(addr_info) |
| 232 | freeaddrinfo(addr_info); |
| 233 | |
| 234 | return retval; |
| 235 | } |
| 236 | |
| 237 | static void |
| 238 | read_from_file(char *buffer, long size, const char *file_name) |
| 239 | { |
| 240 | char ch; |
| 241 | long index=0; |
| 242 | FILE *fp; |
| 243 | |
| 244 | fp = fopen(file_name,"r"); // read mode |
| 245 | |
| 246 | if( fp == NULL ) |
| 247 | { |
| 248 | perror("Error while opening the file.\n"); |
| 249 | exit(EXIT_FAILURE); |
| 250 | } |
| 251 | |
| 252 | printf("The contents of %s file are :\n", file_name); |
| 253 | |
| 254 | while(index<size && ( ch = fgetc(fp) ) != EOF ){ |
| 255 | buffer[index++] = ch; |
| 256 | } |
| 257 | |
| 258 | fclose(fp); |
| 259 | } |
| 260 | |
| 261 | #define ISSUER_CN_PINNING "The Apache Software Foundation" |
| 262 | #define SUBJECT_CN_PINNING "localhost" |
| 263 | #define CERT_SERIAL_NUMBER "1" |
| 264 | |
| 265 | gboolean verify_certificate_sn(X509 *cert, const unsigned char *serial_number) |
| 266 | { |
| 267 | gboolean retval = FALSE; |
| 268 | |
| 269 | ASN1_INTEGER *serial = X509_get_serialNumber(cert); |
| 270 | |
| 271 | BIGNUM *bn = ASN1_INTEGER_to_BN(serial, NULL); |
| 272 | if (!bn) { |
| 273 | fprintf(stderr, "unable to convert ASN1INTEGER to BN\n"); |
| 274 | return EXIT_FAILURE; |
| 275 | } |
| 276 | char *tmp = BN_bn2dec(bn); |
| 277 | if (!tmp) { |
| 278 | g_warning(stderr, "unable to convert BN to decimal string.\n"); |
| 279 | BN_free(bn); |
| 280 | return EXIT_FAILURE; |
| 281 | } |
| 282 | // if (strlen(tmp) >= len) { |
| 283 | // g_warn(stderr, "buffer length shorter than serial number\n"); |
| 284 | // BN_free(bn); |
| 285 | // OPENSSL_free(tmp); |
| 286 | // return EXIT_FAILURE; |
| 287 | // } |
| 288 | if(!strncmp(serial_number, tmp, strlen(serial_number))){ |
| 289 | retval=TRUE; |
| 290 | }else{ |
| 291 | g_warning("Serial number is not valid"); |
| 292 | } |
| 293 | |
| 294 | BN_free(bn); |
| 295 | OPENSSL_free(tmp); |
| 296 | return retval; |
| 297 | } |
| 298 | |
| 299 | gboolean my_access_manager(ThriftTransport * transport, X509 *cert, struct sockaddr_storage *addr, GError **error) |
| 300 | { |
| 301 | ThriftSSLSocket *sslSocket = THRIFT_SSL_SOCKET (transport); |
| 302 | |
| 303 | g_info("Processing access to the server"); |
| 304 | X509_NAME* iname = cert ? X509_get_issuer_name(cert) : NULL; |
| 305 | X509_NAME* sname = cert ? X509_get_subject_name(cert) : NULL; |
| 306 | |
| 307 | /* Issuer is the authority we trust that warrants nothing useful */ |
| 308 | const unsigned char * issuer = get_cn_name(iname); |
| 309 | if(issuer){ |
| 310 | gboolean valid = TRUE; |
| 311 | g_info("Issuer (cn) %s", issuer); |
| 312 | |
| 313 | // Issuer pinning |
| 314 | if(strncmp(ISSUER_CN_PINNING, issuer, strlen(ISSUER_CN_PINNING))){ |
| 315 | g_warning("The Issuer of the certificate is not valid"); |
| 316 | valid=FALSE; |
| 317 | } |
| 318 | OPENSSL_free(issuer); |
| 319 | if(!valid) |
| 320 | return valid; |
| 321 | } |
| 322 | |
| 323 | |
| 324 | /* Subject is who the certificate is issued to by the authority */ |
| 325 | const unsigned char * subject = get_cn_name(sname); |
| 326 | if(subject){ |
| 327 | g_info("Subject (cn) %s", subject); |
| 328 | gboolean valid = TRUE; |
| 329 | |
| 330 | // Subject pinning |
| 331 | if(strncmp(SUBJECT_CN_PINNING, subject, strlen(SUBJECT_CN_PINNING))){ |
| 332 | g_warning("The subject of the certificate is not valid"); |
| 333 | valid=FALSE; |
| 334 | } |
| 335 | |
| 336 | if(!valid) |
| 337 | return valid; |
| 338 | |
| 339 | // Host pinning |
| 340 | if(verify_ip(subject, addr)){ |
| 341 | g_info("Verified subject"); |
| 342 | }else{ |
| 343 | g_info("Cannot verify subject"); |
| 344 | valid=FALSE; |
| 345 | } |
| 346 | OPENSSL_free(subject); |
| 347 | |
| 348 | if(!valid) |
| 349 | return valid; |
| 350 | } |
| 351 | |
| 352 | if(!verify_certificate_sn(cert, CERT_SERIAL_NUMBER)){ |
| 353 | return FALSE; |
| 354 | }else{ |
| 355 | g_info("Verified serial number"); |
| 356 | } |
| 357 | |
| 358 | return TRUE; |
| 359 | |
| 360 | } |
| 361 | |
| 362 | |
| 363 | |
| 364 | |
| 365 | #ifdef BUILD_SERVER |
| 366 | static void |
| 367 | test_ssl_authorization_manager(void) |
| 368 | { |
| 369 | int status=0; |
| 370 | pid_t pid; |
| 371 | ThriftSSLSocket *tSSLsocket = NULL; |
| 372 | ThriftTransport *transport = NULL; |
| 373 | // int port = 51199; |
| 374 | int port = 443; |
| 375 | GError *error=NULL; |
| 376 | |
| 377 | guchar buf[17] = TEST_DATA; /* a buffer */ |
| 378 | |
| 379 | // pid = fork (); |
| 380 | // assert ( pid >= 0 ); |
| 381 | // |
| 382 | // if ( pid == 0 ) |
| 383 | // { |
| 384 | // /* child listens */ |
| 385 | // thrift_ssl_socket_server (port); |
| 386 | // exit (0); |
| 387 | // } else { |
| 388 | /* parent connects, wait a bit for the socket to be created */ |
| 389 | sleep (1); |
| 390 | |
| 391 | // Test against level2 owncloud certificate |
| 392 | tSSLsocket = thrift_ssl_socket_new_with_host(SSLTLS, "localhost", port, &error); |
| 393 | thrift_ssl_socket_set_manager(tSSLsocket, my_access_manager); // Install pinning manager |
| 394 | //thrift_ssl_load_cert_from_file(tSSLsocket, "./owncloud.level2crm.pem"); |
| 395 | unsigned char cert_buffer[65534]; |
| 396 | read_from_file(cert_buffer, 65534, "../../keys/client.pem"); |
| 397 | if(!thrift_ssl_load_cert_from_buffer(tSSLsocket, cert_buffer)){ |
| 398 | g_warning("Certificates cannot be loaded!"); |
| 399 | } |
| 400 | |
| 401 | transport = THRIFT_TRANSPORT (tSSLsocket); |
| 402 | assert (thrift_ssl_socket_open (transport, NULL) == TRUE); |
| 403 | assert (thrift_ssl_socket_is_open (transport)); |
| 404 | |
| 405 | thrift_ssl_socket_write (transport, buf, 17, NULL); |
| 406 | |
| 407 | /* write fail */ |
| 408 | send_error = 1; |
| 409 | // thrift_ssl_socket_write (transport, buf, 1, NULL); |
| 410 | // send_error = 0; |
| 411 | |
| 412 | // thrift_ssl_socket_write_end (transport, NULL); |
| 413 | // thrift_ssl_socket_flush (transport, NULL); |
| 414 | thrift_ssl_socket_close (transport, NULL); |
| 415 | g_object_unref (tSSLsocket); |
| 416 | |
| 417 | // assert ( wait (&status) == pid ); |
| 418 | assert ( status == 0 ); |
| 419 | // } |
| 420 | } |
| 421 | #endif |
| 422 | |
| 423 | |
| 424 | /* test ThriftSocket's peek() implementation */ |
| 425 | //static void |
| 426 | //test_ssl_peek(void) |
| 427 | //{ |
| 428 | // gint status; |
| 429 | // pid_t pid; |
| 430 | // guint port = 51199; |
| 431 | // gchar data = 'A'; |
| 432 | // ThriftTransport *client_transport; |
| 433 | // GError *error = NULL; |
| 434 | // |
| 435 | // client_transport = g_object_new (THRIFT_TYPE_SSL_SOCKET, |
| 436 | // "hostname", "localhost", |
| 437 | // "port", port, |
| 438 | // NULL); |
| 439 | // |
| 440 | // /* thrift_transport_peek returns FALSE when the socket is closed */ |
| 441 | // g_assert (thrift_transport_is_open (client_transport) == FALSE); |
| 442 | // g_assert (thrift_transport_peek (client_transport, &error) == FALSE); |
| 443 | // g_assert (error == NULL); |
| 444 | // |
| 445 | // pid = fork (); |
| 446 | // g_assert (pid >= 0); |
| 447 | // |
| 448 | // if (pid == 0) |
| 449 | // { |
| 450 | // ThriftServerTransport *server_transport = NULL; |
| 451 | // |
| 452 | // g_object_unref (client_transport); |
| 453 | // |
| 454 | // /* child listens */ |
| 455 | // server_transport = g_object_new (THRIFT_TYPE_SERVER_SOCKET, |
| 456 | // "port", port, |
| 457 | // NULL); |
| 458 | // g_assert (server_transport != NULL); |
| 459 | // |
| 460 | // thrift_server_transport_listen (server_transport, &error); |
| 461 | // g_assert (error == NULL); |
| 462 | // |
| 463 | // client_transport = g_object_new |
| 464 | // (THRIFT_TYPE_BUFFERED_TRANSPORT, |
| 465 | // "transport", thrift_server_transport_accept (server_transport, &error), |
| 466 | // "r_buf_size", 0, |
| 467 | // "w_buf_size", sizeof data, |
| 468 | // NULL); |
| 469 | // g_assert (error == NULL); |
| 470 | // g_assert (client_transport != NULL); |
| 471 | // |
| 472 | // /* write exactly one character to the client */ |
| 473 | // g_assert (thrift_transport_write (client_transport, |
| 474 | // &data, |
| 475 | // sizeof data, |
| 476 | // &error) == TRUE); |
| 477 | // |
| 478 | // thrift_transport_flush (client_transport, &error); |
| 479 | // thrift_transport_write_end (client_transport, &error); |
| 480 | // thrift_transport_close (client_transport, &error); |
| 481 | // |
| 482 | // g_object_unref (client_transport); |
| 483 | // g_object_unref (server_transport); |
| 484 | // |
| 485 | // exit (0); |
| 486 | // } |
| 487 | // else { |
| 488 | // /* parent connects, wait a bit for the socket to be created */ |
| 489 | // sleep (1); |
| 490 | // |
| 491 | // /* connect to the child */ |
| 492 | // thrift_transport_open (client_transport, &error); |
| 493 | // g_assert (error == NULL); |
| 494 | // g_assert (thrift_transport_is_open (client_transport) == TRUE); |
| 495 | // |
| 496 | // /* thrift_transport_peek returns TRUE when the socket is open and there is |
| 497 | // data available to be read */ |
| 498 | // g_assert (thrift_transport_peek (client_transport, &error) == TRUE); |
| 499 | // g_assert (error == NULL); |
| 500 | // |
| 501 | // /* read exactly one character from the server */ |
| 502 | // g_assert_cmpint (thrift_transport_read (client_transport, |
| 503 | // &data, |
| 504 | // sizeof data, |
| 505 | // &error), ==, sizeof data); |
| 506 | // |
| 507 | // /* thrift_transport_peek returns FALSE when the socket is open but there is |
| 508 | // no (more) data available to be read */ |
| 509 | // g_assert (thrift_transport_is_open (client_transport) == TRUE); |
| 510 | // g_assert (thrift_transport_peek (client_transport, &error) == FALSE); |
| 511 | // g_assert (error == NULL); |
| 512 | // |
| 513 | // thrift_transport_read_end (client_transport, &error); |
| 514 | // thrift_transport_close (client_transport, &error); |
| 515 | // |
| 516 | // g_object_unref (client_transport); |
| 517 | // |
| 518 | // g_assert (wait (&status) == pid); |
| 519 | // g_assert (status == 0); |
| 520 | // } |
| 521 | //} |
| 522 | |
| 523 | static void |
| 524 | thrift_ssl_socket_server (const int port) |
| 525 | { |
| 526 | int bytes = 0; |
| 527 | ThriftServerTransport *transport = NULL; |
| 528 | ThriftTransport *client = NULL; |
| 529 | guchar buf[10]; /* a buffer */ |
| 530 | guchar match[10] = TEST_DATA; |
| 531 | |
| 532 | ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, |
| 533 | "port", port, NULL); |
| 534 | |
| 535 | transport = THRIFT_SERVER_TRANSPORT (tsocket); |
| 536 | thrift_server_transport_listen (transport, NULL); |
| 537 | client = thrift_server_transport_accept (transport, NULL); |
| 538 | assert (client != NULL); |
| 539 | |
| 540 | /* read 10 bytes */ |
| 541 | bytes = thrift_ssl_socket_read (client, buf, 10, NULL); |
| 542 | assert (bytes == 10); /* make sure we've read 10 bytes */ |
| 543 | assert ( memcmp(buf, match, 10) == 0 ); /* make sure what we got matches */ |
| 544 | |
| 545 | /* failed read */ |
| 546 | recv_error = 1; |
| 547 | thrift_ssl_socket_read (client, buf, 1, NULL); |
| 548 | recv_error = 0; |
| 549 | |
| 550 | thrift_ssl_socket_read_end (client, NULL); |
| 551 | thrift_ssl_socket_close (client, NULL); |
| 552 | g_object_unref (tsocket); |
| 553 | g_object_unref (client); |
| 554 | } |
| 555 | |
| 556 | int |
| 557 | main(int argc, char *argv[]) |
| 558 | { |
| 559 | int retval; |
| 560 | #if (!GLIB_CHECK_VERSION (2, 36, 0)) |
| 561 | g_type_init(); |
| 562 | #endif |
| 563 | |
| 564 | g_test_init (&argc, &argv, NULL); |
| 565 | |
| 566 | thrift_ssl_socket_initialize_openssl(); |
| 567 | |
| 568 | g_test_add_func ("/testtransportsslsocket/CreateAndDestroy", test_ssl_create_and_destroy); |
| 569 | g_test_add_func ("/testtransportsslsocket/CreateAndSetProperties", test_ssl_create_and_set_properties); |
| 570 | g_test_add_func ("/testtransportsslsocket/OpenAndClose", test_ssl_open_and_close); |
| 571 | // This test is disabled because server is not ready |
| 572 | // g_test_add_func ("/testtransportsslsocket/AuthorizationManagerPinning", test_ssl_authorization_manager); |
| 573 | // g_test_add_func ("/testtransportsslsocket/Peek", test_ssl_peek); |
| 574 | |
| 575 | retval = g_test_run (); |
| 576 | |
| 577 | thrift_ssl_socket_finalize_openssl(); |
| 578 | |
| 579 | return retval; |
| 580 | } |
| 581 | |