2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include <folly/io/async/test/AsyncSSLSocketTest.h>
21 #include <folly/io/async/AsyncSSLSocket.h>
22 #include <folly/io/async/EventBase.h>
23 #include <folly/SocketAddress.h>
25 #include <folly/io/async/test/BlockingSocket.h>
27 #include <gtest/gtest.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/tcp.h>
37 #include <folly/io/Cursor.h>
47 uint32_t TestSSLAsyncCacheServer::asyncCallbacks_ = 0;
48 uint32_t TestSSLAsyncCacheServer::asyncLookups_ = 0;
49 uint32_t TestSSLAsyncCacheServer::lookupDelay_ = 0;
51 const char* testCert = "folly/io/async/test/certs/tests-cert.pem";
52 const char* testKey = "folly/io/async/test/certs/tests-key.pem";
53 const char* testCA = "folly/io/async/test/certs/ca-cert.pem";
55 constexpr size_t SSLClient::kMaxReadBufferSz;
56 constexpr size_t SSLClient::kMaxReadsPerEvent;
58 TestSSLServer::TestSSLServer(SSLServerAcceptCallbackBase *acb) :
59 ctx_(new folly::SSLContext),
61 socket_(folly::AsyncServerSocket::newSocket(&evb_)) {
62 // Set up the SSL context
63 ctx_->loadCertificate(testCert);
64 ctx_->loadPrivateKey(testKey);
65 ctx_->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
70 //set up the listening socket
72 socket_->getAddress(&address_);
74 socket_->addAcceptCallback(acb_, &evb_);
75 socket_->startAccepting();
77 int ret = pthread_create(&thread_, nullptr, Main, this);
80 std::cerr << "Accepting connections on " << address_ << std::endl;
83 void getfds(int fds[2]) {
84 if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
85 FAIL() << "failed to create socketpair: " << strerror(errno);
87 for (int idx = 0; idx < 2; ++idx) {
88 int flags = fcntl(fds[idx], F_GETFL, 0);
90 FAIL() << "failed to get flags for socket " << idx << ": "
93 if (fcntl(fds[idx], F_SETFL, flags | O_NONBLOCK) != 0) {
94 FAIL() << "failed to put socket " << idx << " in non-blocking mode: "
101 std::shared_ptr<folly::SSLContext> clientCtx,
102 std::shared_ptr<folly::SSLContext> serverCtx) {
103 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
105 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
106 serverCtx->loadCertificate(
108 serverCtx->loadPrivateKey(
113 EventBase* eventBase,
114 AsyncSSLSocket::UniquePtr* clientSock,
115 AsyncSSLSocket::UniquePtr* serverSock) {
116 auto clientCtx = std::make_shared<folly::SSLContext>();
117 auto serverCtx = std::make_shared<folly::SSLContext>();
120 getctx(clientCtx, serverCtx);
121 clientSock->reset(new AsyncSSLSocket(
122 clientCtx, eventBase, fds[0], false));
123 serverSock->reset(new AsyncSSLSocket(
124 serverCtx, eventBase, fds[1], true));
126 // (*clientSock)->setSendTimeout(100);
127 // (*serverSock)->setSendTimeout(100);
132 * Test connecting to, writing to, reading from, and closing the
133 * connection to the SSL server.
135 TEST(AsyncSSLSocketTest, ConnectWriteReadClose) {
136 // Start listening on a local port
137 WriteCallbackBase writeCallback;
138 ReadCallback readCallback(&writeCallback);
139 HandshakeCallback handshakeCallback(&readCallback);
140 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
141 TestSSLServer server(&acceptCallback);
143 // Set up SSL context.
144 std::shared_ptr<SSLContext> sslContext(new SSLContext());
145 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
146 //sslContext->loadTrustedCertificates("./trusted-ca-certificate.pem");
147 //sslContext->authenticate(true, false);
150 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
156 memset(buf, 'a', sizeof(buf));
157 socket->write(buf, sizeof(buf));
160 uint8_t readbuf[128];
161 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
162 EXPECT_EQ(bytesRead, 128);
163 EXPECT_EQ(memcmp(buf, readbuf, bytesRead), 0);
168 cerr << "ConnectWriteReadClose test completed" << endl;
172 * Negative test for handshakeError().
174 TEST(AsyncSSLSocketTest, HandshakeError) {
175 // Start listening on a local port
176 WriteCallbackBase writeCallback;
177 ReadCallback readCallback(&writeCallback);
178 HandshakeCallback handshakeCallback(&readCallback);
179 HandshakeErrorCallback acceptCallback(&handshakeCallback);
180 TestSSLServer server(&acceptCallback);
182 // Set up SSL context.
183 std::shared_ptr<SSLContext> sslContext(new SSLContext());
184 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
187 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
194 uint8_t readbuf[128];
195 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
196 } catch (AsyncSocketException &e) {
203 cerr << "HandshakeError test completed" << endl;
207 * Negative test for readError().
209 TEST(AsyncSSLSocketTest, ReadError) {
210 // Start listening on a local port
211 WriteCallbackBase writeCallback;
212 ReadErrorCallback readCallback(&writeCallback);
213 HandshakeCallback handshakeCallback(&readCallback);
214 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
215 TestSSLServer server(&acceptCallback);
217 // Set up SSL context.
218 std::shared_ptr<SSLContext> sslContext(new SSLContext());
219 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
222 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
226 // write something to trigger ssl handshake
228 memset(buf, 'a', sizeof(buf));
229 socket->write(buf, sizeof(buf));
232 cerr << "ReadError test completed" << endl;
236 * Negative test for writeError().
238 TEST(AsyncSSLSocketTest, WriteError) {
239 // Start listening on a local port
240 WriteCallbackBase writeCallback;
241 WriteErrorCallback readCallback(&writeCallback);
242 HandshakeCallback handshakeCallback(&readCallback);
243 SSLServerAcceptCallback acceptCallback(&handshakeCallback);
244 TestSSLServer server(&acceptCallback);
246 // Set up SSL context.
247 std::shared_ptr<SSLContext> sslContext(new SSLContext());
248 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
251 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
255 // write something to trigger ssl handshake
257 memset(buf, 'a', sizeof(buf));
258 socket->write(buf, sizeof(buf));
261 cerr << "WriteError test completed" << endl;
265 * Test a socket with TCP_NODELAY unset.
267 TEST(AsyncSSLSocketTest, SocketWithDelay) {
268 // Start listening on a local port
269 WriteCallbackBase writeCallback;
270 ReadCallback readCallback(&writeCallback);
271 HandshakeCallback handshakeCallback(&readCallback);
272 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
273 TestSSLServer server(&acceptCallback);
275 // Set up SSL context.
276 std::shared_ptr<SSLContext> sslContext(new SSLContext());
277 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
280 auto socket = std::make_shared<BlockingSocket>(server.getAddress(),
286 memset(buf, 'a', sizeof(buf));
287 socket->write(buf, sizeof(buf));
290 uint8_t readbuf[128];
291 uint32_t bytesRead = socket->readAll(readbuf, sizeof(readbuf));
292 EXPECT_EQ(bytesRead, 128);
293 EXPECT_EQ(memcmp(buf, readbuf, bytesRead), 0);
298 cerr << "SocketWithDelay test completed" << endl;
301 TEST(AsyncSSLSocketTest, NpnTestOverlap) {
303 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
304 std::shared_ptr<SSLContext> serverCtx(new SSLContext);;
307 getctx(clientCtx, serverCtx);
309 clientCtx->setAdvertisedNextProtocols({"blub","baz"});
310 serverCtx->setAdvertisedNextProtocols({"foo","bar","baz"});
312 AsyncSSLSocket::UniquePtr clientSock(
313 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
314 AsyncSSLSocket::UniquePtr serverSock(
315 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
316 NpnClient client(std::move(clientSock));
317 NpnServer server(std::move(serverSock));
321 EXPECT_TRUE(client.nextProtoLength != 0);
322 EXPECT_EQ(client.nextProtoLength, server.nextProtoLength);
323 EXPECT_EQ(memcmp(client.nextProto, server.nextProto,
324 server.nextProtoLength), 0);
325 string selected((const char*)client.nextProto, client.nextProtoLength);
326 EXPECT_EQ(selected.compare("baz"), 0);
329 TEST(AsyncSSLSocketTest, NpnTestUnset) {
330 // Identical to above test, except that we want unset NPN before
333 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
334 std::shared_ptr<SSLContext> serverCtx(new SSLContext);;
337 getctx(clientCtx, serverCtx);
339 clientCtx->setAdvertisedNextProtocols({"blub","baz"});
340 serverCtx->setAdvertisedNextProtocols({"foo","bar","baz"});
342 AsyncSSLSocket::UniquePtr clientSock(
343 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
344 AsyncSSLSocket::UniquePtr serverSock(
345 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
347 // unsetting NPN for any of [client, server] is enought to make NPN not
349 clientCtx->unsetNextProtocols();
351 NpnClient client(std::move(clientSock));
352 NpnServer server(std::move(serverSock));
356 EXPECT_TRUE(client.nextProtoLength == 0);
357 EXPECT_TRUE(server.nextProtoLength == 0);
358 EXPECT_TRUE(client.nextProto == nullptr);
359 EXPECT_TRUE(server.nextProto == nullptr);
362 TEST(AsyncSSLSocketTest, NpnTestNoOverlap) {
364 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
365 std::shared_ptr<SSLContext> serverCtx(new SSLContext);;
368 getctx(clientCtx, serverCtx);
370 clientCtx->setAdvertisedNextProtocols({"blub"});
371 serverCtx->setAdvertisedNextProtocols({"foo","bar","baz"});
373 AsyncSSLSocket::UniquePtr clientSock(
374 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
375 AsyncSSLSocket::UniquePtr serverSock(
376 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
377 NpnClient client(std::move(clientSock));
378 NpnServer server(std::move(serverSock));
382 EXPECT_TRUE(client.nextProtoLength != 0);
383 EXPECT_EQ(client.nextProtoLength, server.nextProtoLength);
384 EXPECT_EQ(memcmp(client.nextProto, server.nextProto,
385 server.nextProtoLength), 0);
386 string selected((const char*)client.nextProto, client.nextProtoLength);
387 EXPECT_EQ(selected.compare("blub"), 0);
390 TEST(AsyncSSLSocketTest, RandomizedNpnTest) {
391 // Probability that this test will fail is 2^-64, which could be considered
393 const int kTries = 64;
395 std::set<string> selectedProtocols;
396 for (int i = 0; i < kTries; ++i) {
398 std::shared_ptr<SSLContext> clientCtx = std::make_shared<SSLContext>();
399 std::shared_ptr<SSLContext> serverCtx = std::make_shared<SSLContext>();
402 getctx(clientCtx, serverCtx);
404 clientCtx->setAdvertisedNextProtocols({"foo", "bar", "baz"});
405 serverCtx->setRandomizedAdvertisedNextProtocols({{1, {"foo"}},
409 AsyncSSLSocket::UniquePtr clientSock(
410 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
411 AsyncSSLSocket::UniquePtr serverSock(
412 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
413 NpnClient client(std::move(clientSock));
414 NpnServer server(std::move(serverSock));
418 EXPECT_TRUE(client.nextProtoLength != 0);
419 EXPECT_EQ(client.nextProtoLength, server.nextProtoLength);
420 EXPECT_EQ(memcmp(client.nextProto, server.nextProto,
421 server.nextProtoLength), 0);
422 string selected((const char*)client.nextProto, client.nextProtoLength);
423 selectedProtocols.insert(selected);
425 EXPECT_EQ(selectedProtocols.size(), 2);
429 #ifndef OPENSSL_NO_TLSEXT
431 * 1. Client sends TLSEXT_HOSTNAME in client hello.
432 * 2. Server found a match SSL_CTX and use this SSL_CTX to
433 * continue the SSL handshake.
434 * 3. Server sends back TLSEXT_HOSTNAME in server hello.
436 TEST(AsyncSSLSocketTest, SNITestMatch) {
438 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
439 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
440 // Use the same SSLContext to continue the handshake after
441 // tlsext_hostname match.
442 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
443 const std::string serverName("xyz.newdev.facebook.com");
446 getctx(clientCtx, dfServerCtx);
448 AsyncSSLSocket::UniquePtr clientSock(
449 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
450 AsyncSSLSocket::UniquePtr serverSock(
451 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
452 SNIClient client(std::move(clientSock));
453 SNIServer server(std::move(serverSock),
460 EXPECT_TRUE(client.serverNameMatch);
461 EXPECT_TRUE(server.serverNameMatch);
465 * 1. Client sends TLSEXT_HOSTNAME in client hello.
466 * 2. Server cannot find a matching SSL_CTX and continue to use
467 * the current SSL_CTX to do the handshake.
468 * 3. Server does not send back TLSEXT_HOSTNAME in server hello.
470 TEST(AsyncSSLSocketTest, SNITestNotMatch) {
472 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
473 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
474 // Use the same SSLContext to continue the handshake after
475 // tlsext_hostname match.
476 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
477 const std::string clientRequestingServerName("foo.com");
478 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
482 getctx(clientCtx, dfServerCtx);
484 AsyncSSLSocket::UniquePtr clientSock(
485 new AsyncSSLSocket(clientCtx,
488 clientRequestingServerName));
489 AsyncSSLSocket::UniquePtr serverSock(
490 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
491 SNIClient client(std::move(clientSock));
492 SNIServer server(std::move(serverSock),
495 serverExpectedServerName);
499 EXPECT_TRUE(!client.serverNameMatch);
500 EXPECT_TRUE(!server.serverNameMatch);
503 * 1. Client sends TLSEXT_HOSTNAME in client hello.
504 * 2. We then change the serverName.
505 * 3. We expect that we get 'false' as the result for serNameMatch.
508 TEST(AsyncSSLSocketTest, SNITestChangeServerName) {
510 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
511 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
512 // Use the same SSLContext to continue the handshake after
513 // tlsext_hostname match.
514 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
515 const std::string serverName("xyz.newdev.facebook.com");
518 getctx(clientCtx, dfServerCtx);
520 AsyncSSLSocket::UniquePtr clientSock(
521 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], serverName));
522 //Change the server name
523 std::string newName("new.com");
524 clientSock->setServerName(newName);
525 AsyncSSLSocket::UniquePtr serverSock(
526 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
527 SNIClient client(std::move(clientSock));
528 SNIServer server(std::move(serverSock),
535 EXPECT_TRUE(!client.serverNameMatch);
539 * 1. Client does not send TLSEXT_HOSTNAME in client hello.
540 * 2. Server does not send back TLSEXT_HOSTNAME in server hello.
542 TEST(AsyncSSLSocketTest, SNITestClientHelloNoHostname) {
544 std::shared_ptr<SSLContext> clientCtx(new SSLContext);
545 std::shared_ptr<SSLContext> dfServerCtx(new SSLContext);
546 // Use the same SSLContext to continue the handshake after
547 // tlsext_hostname match.
548 std::shared_ptr<SSLContext> hskServerCtx(dfServerCtx);
549 const std::string serverExpectedServerName("xyz.newdev.facebook.com");
553 getctx(clientCtx, dfServerCtx);
555 AsyncSSLSocket::UniquePtr clientSock(
556 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
557 AsyncSSLSocket::UniquePtr serverSock(
558 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
559 SNIClient client(std::move(clientSock));
560 SNIServer server(std::move(serverSock),
563 serverExpectedServerName);
567 EXPECT_TRUE(!client.serverNameMatch);
568 EXPECT_TRUE(!server.serverNameMatch);
573 * Test SSL client socket
575 TEST(AsyncSSLSocketTest, SSLClientTest) {
576 // Start listening on a local port
577 WriteCallbackBase writeCallback;
578 ReadCallback readCallback(&writeCallback);
579 HandshakeCallback handshakeCallback(&readCallback);
580 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
581 TestSSLServer server(&acceptCallback);
585 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
589 EventBaseAborter eba(&eventBase, 3000);
592 EXPECT_EQ(client->getMiss(), 1);
593 EXPECT_EQ(client->getHit(), 0);
595 cerr << "SSLClientTest test completed" << endl;
600 * Test SSL client socket session re-use
602 TEST(AsyncSSLSocketTest, SSLClientTestReuse) {
603 // Start listening on a local port
604 WriteCallbackBase writeCallback;
605 ReadCallback readCallback(&writeCallback);
606 HandshakeCallback handshakeCallback(&readCallback);
607 SSLServerAcceptCallbackDelay acceptCallback(&handshakeCallback);
608 TestSSLServer server(&acceptCallback);
612 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
616 EventBaseAborter eba(&eventBase, 3000);
619 EXPECT_EQ(client->getMiss(), 1);
620 EXPECT_EQ(client->getHit(), 9);
622 cerr << "SSLClientTestReuse test completed" << endl;
626 * Test SSL client socket timeout
628 TEST(AsyncSSLSocketTest, SSLClientTimeoutTest) {
629 // Start listening on a local port
630 EmptyReadCallback readCallback;
631 HandshakeCallback handshakeCallback(&readCallback,
632 HandshakeCallback::EXPECT_ERROR);
633 HandshakeTimeoutCallback acceptCallback(&handshakeCallback);
634 TestSSLServer server(&acceptCallback);
638 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
640 client->connect(true /* write before connect completes */);
641 EventBaseAborter eba(&eventBase, 3000);
645 // This is checking that the connectError callback precedes any queued
646 // writeError callbacks. This matches AsyncSocket's behavior
647 EXPECT_EQ(client->getWriteAfterConnectErrors(), 1);
648 EXPECT_EQ(client->getErrors(), 1);
649 EXPECT_EQ(client->getMiss(), 0);
650 EXPECT_EQ(client->getHit(), 0);
652 cerr << "SSLClientTimeoutTest test completed" << endl;
657 * Test SSL server async cache
659 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTest) {
660 // Start listening on a local port
661 WriteCallbackBase writeCallback;
662 ReadCallback readCallback(&writeCallback);
663 HandshakeCallback handshakeCallback(&readCallback);
664 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
665 TestSSLAsyncCacheServer server(&acceptCallback);
669 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
673 EventBaseAborter eba(&eventBase, 3000);
676 EXPECT_EQ(server.getAsyncCallbacks(), 18);
677 EXPECT_EQ(server.getAsyncLookups(), 9);
678 EXPECT_EQ(client->getMiss(), 10);
679 EXPECT_EQ(client->getHit(), 0);
681 cerr << "SSLServerAsyncCacheTest test completed" << endl;
686 * Test SSL server accept timeout with cache path
688 TEST(AsyncSSLSocketTest, SSLServerTimeoutTest) {
689 // Start listening on a local port
690 WriteCallbackBase writeCallback;
691 ReadCallback readCallback(&writeCallback);
692 EmptyReadCallback clientReadCallback;
693 HandshakeCallback handshakeCallback(&readCallback);
694 SSLServerAcceptCallback acceptCallback(&handshakeCallback, 50);
695 TestSSLAsyncCacheServer server(&acceptCallback);
699 // only do a TCP connect
700 std::shared_ptr<AsyncSocket> sock = AsyncSocket::newSocket(&eventBase);
701 sock->connect(nullptr, server.getAddress());
702 clientReadCallback.tcpSocket_ = sock;
703 sock->setReadCB(&clientReadCallback);
705 EventBaseAborter eba(&eventBase, 3000);
708 EXPECT_EQ(readCallback.state, STATE_WAITING);
710 cerr << "SSLServerTimeoutTest test completed" << endl;
714 * Test SSL server accept timeout with cache path
716 TEST(AsyncSSLSocketTest, SSLServerAsyncCacheTimeoutTest) {
717 // Start listening on a local port
718 WriteCallbackBase writeCallback;
719 ReadCallback readCallback(&writeCallback);
720 HandshakeCallback handshakeCallback(&readCallback);
721 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback, 50);
722 TestSSLAsyncCacheServer server(&acceptCallback);
726 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
730 EventBaseAborter eba(&eventBase, 3000);
733 EXPECT_EQ(server.getAsyncCallbacks(), 1);
734 EXPECT_EQ(server.getAsyncLookups(), 1);
735 EXPECT_EQ(client->getErrors(), 1);
736 EXPECT_EQ(client->getMiss(), 1);
737 EXPECT_EQ(client->getHit(), 0);
739 cerr << "SSLServerAsyncCacheTimeoutTest test completed" << endl;
743 * Test SSL server accept timeout with cache path
745 TEST(AsyncSSLSocketTest, SSLServerCacheCloseTest) {
746 // Start listening on a local port
747 WriteCallbackBase writeCallback;
748 ReadCallback readCallback(&writeCallback);
749 HandshakeCallback handshakeCallback(&readCallback,
750 HandshakeCallback::EXPECT_ERROR);
751 SSLServerAsyncCacheAcceptCallback acceptCallback(&handshakeCallback);
752 TestSSLAsyncCacheServer server(&acceptCallback, 500);
756 std::shared_ptr<SSLClient> client(new SSLClient(&eventBase, server.getAddress(),
760 EventBaseAborter eba(&eventBase, 3000);
763 server.getEventBase().runInEventBaseThread([&handshakeCallback]{
764 handshakeCallback.closeSocket();});
765 // give time for the cache lookup to come back and find it closed
768 EXPECT_EQ(server.getAsyncCallbacks(), 1);
769 EXPECT_EQ(server.getAsyncLookups(), 1);
770 EXPECT_EQ(client->getErrors(), 1);
771 EXPECT_EQ(client->getMiss(), 1);
772 EXPECT_EQ(client->getHit(), 0);
774 cerr << "SSLServerCacheCloseTest test completed" << endl;
778 * Verify Client Ciphers obtained using SSL MSG Callback.
780 TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
782 auto clientCtx = std::make_shared<SSLContext>();
783 auto serverCtx = std::make_shared<SSLContext>();
784 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
785 serverCtx->ciphers("RSA:!SHA:!NULL:!SHA256@STRENGTH");
786 serverCtx->loadPrivateKey(testKey);
787 serverCtx->loadCertificate(testCert);
788 serverCtx->loadTrustedCertificates(testCA);
789 serverCtx->loadClientCAList(testCA);
791 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
792 clientCtx->ciphers("RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5");
793 clientCtx->loadPrivateKey(testKey);
794 clientCtx->loadCertificate(testCert);
795 clientCtx->loadTrustedCertificates(testCA);
800 AsyncSSLSocket::UniquePtr clientSock(
801 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
802 AsyncSSLSocket::UniquePtr serverSock(
803 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
805 SSLHandshakeClient client(std::move(clientSock), true, true);
806 SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);
810 EXPECT_EQ(server.clientCiphers_,
811 "RC4-SHA:AES128-SHA:AES256-SHA:RC4-MD5:00ff");
812 EXPECT_TRUE(client.handshakeVerify_);
813 EXPECT_TRUE(client.handshakeSuccess_);
814 EXPECT_TRUE(!client.handshakeError_);
815 EXPECT_TRUE(server.handshakeVerify_);
816 EXPECT_TRUE(server.handshakeSuccess_);
817 EXPECT_TRUE(!server.handshakeError_);
820 TEST(AsyncSSLSocketTest, SSLParseClientHelloOnePacket) {
822 auto ctx = std::make_shared<SSLContext>();
828 uint8_t majorVersion = 18;
829 uint8_t minorVersion = 25;
831 // Create callback buf
832 auto buf = IOBuf::create(bufLen);
834 folly::io::RWPrivateCursor cursor(buf.get());
835 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
836 cursor.write<uint16_t>(0);
837 cursor.write<uint8_t>(38);
838 cursor.write<uint8_t>(majorVersion);
839 cursor.write<uint8_t>(minorVersion);
841 cursor.write<uint32_t>(0);
843 SSL* ssl = ctx->createSSL();
844 SCOPE_EXIT { SSL_free(ssl); };
845 AsyncSSLSocket::UniquePtr sock(
846 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
847 sock->enableClientHelloParsing();
849 // Test client hello parsing in one packet
850 AsyncSSLSocket::clientHelloParsingCallback(
851 0, 0, SSL3_RT_HANDSHAKE, buf->data(), buf->length(), ssl, sock.get());
854 auto parsedClientHello = sock->getClientHelloInfo();
855 EXPECT_TRUE(parsedClientHello != nullptr);
856 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
857 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
860 TEST(AsyncSSLSocketTest, SSLParseClientHelloTwoPackets) {
862 auto ctx = std::make_shared<SSLContext>();
868 uint8_t majorVersion = 18;
869 uint8_t minorVersion = 25;
871 // Create callback buf
872 auto buf = IOBuf::create(bufLen);
874 folly::io::RWPrivateCursor cursor(buf.get());
875 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
876 cursor.write<uint16_t>(0);
877 cursor.write<uint8_t>(38);
878 cursor.write<uint8_t>(majorVersion);
879 cursor.write<uint8_t>(minorVersion);
881 cursor.write<uint32_t>(0);
883 SSL* ssl = ctx->createSSL();
884 SCOPE_EXIT { SSL_free(ssl); };
885 AsyncSSLSocket::UniquePtr sock(
886 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
887 sock->enableClientHelloParsing();
889 // Test parsing with two packets with first packet size < 3
890 auto bufCopy = folly::IOBuf::copyBuffer(buf->data(), 2);
891 AsyncSSLSocket::clientHelloParsingCallback(
892 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
895 bufCopy = folly::IOBuf::copyBuffer(buf->data() + 2, buf->length() - 2);
896 AsyncSSLSocket::clientHelloParsingCallback(
897 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
901 auto parsedClientHello = sock->getClientHelloInfo();
902 EXPECT_TRUE(parsedClientHello != nullptr);
903 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
904 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
907 TEST(AsyncSSLSocketTest, SSLParseClientHelloMultiplePackets) {
909 auto ctx = std::make_shared<SSLContext>();
915 uint8_t majorVersion = 18;
916 uint8_t minorVersion = 25;
918 // Create callback buf
919 auto buf = IOBuf::create(bufLen);
921 folly::io::RWPrivateCursor cursor(buf.get());
922 cursor.write<uint8_t>(SSL3_MT_CLIENT_HELLO);
923 cursor.write<uint16_t>(0);
924 cursor.write<uint8_t>(38);
925 cursor.write<uint8_t>(majorVersion);
926 cursor.write<uint8_t>(minorVersion);
928 cursor.write<uint32_t>(0);
930 SSL* ssl = ctx->createSSL();
931 SCOPE_EXIT { SSL_free(ssl); };
932 AsyncSSLSocket::UniquePtr sock(
933 new AsyncSSLSocket(ctx, &eventBase, fds[0], true));
934 sock->enableClientHelloParsing();
936 // Test parsing with multiple small packets
937 for (uint64_t i = 0; i < buf->length(); i += 3) {
938 auto bufCopy = folly::IOBuf::copyBuffer(
939 buf->data() + i, std::min((uint64_t)3, buf->length() - i));
940 AsyncSSLSocket::clientHelloParsingCallback(
941 0, 0, SSL3_RT_HANDSHAKE, bufCopy->data(), bufCopy->length(),
946 auto parsedClientHello = sock->getClientHelloInfo();
947 EXPECT_TRUE(parsedClientHello != nullptr);
948 EXPECT_EQ(parsedClientHello->clientHelloMajorVersion_, majorVersion);
949 EXPECT_EQ(parsedClientHello->clientHelloMinorVersion_, minorVersion);
953 * Verify sucessful behavior of SSL certificate validation.
955 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSuccess) {
957 auto clientCtx = std::make_shared<SSLContext>();
958 auto dfServerCtx = std::make_shared<SSLContext>();
962 getctx(clientCtx, dfServerCtx);
964 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
965 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
967 AsyncSSLSocket::UniquePtr clientSock(
968 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
969 AsyncSSLSocket::UniquePtr serverSock(
970 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
972 SSLHandshakeClient client(std::move(clientSock), true, true);
973 clientCtx->loadTrustedCertificates(testCA);
975 SSLHandshakeServer server(std::move(serverSock), true, true);
979 EXPECT_TRUE(client.handshakeVerify_);
980 EXPECT_TRUE(client.handshakeSuccess_);
981 EXPECT_TRUE(!client.handshakeError_);
982 EXPECT_TRUE(!server.handshakeVerify_);
983 EXPECT_TRUE(server.handshakeSuccess_);
984 EXPECT_TRUE(!server.handshakeError_);
988 * Verify that the client's verification callback is able to fail SSL
989 * connection establishment.
991 TEST(AsyncSSLSocketTest, SSLHandshakeValidationFailure) {
993 auto clientCtx = std::make_shared<SSLContext>();
994 auto dfServerCtx = std::make_shared<SSLContext>();
998 getctx(clientCtx, dfServerCtx);
1000 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1001 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1003 AsyncSSLSocket::UniquePtr clientSock(
1004 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1005 AsyncSSLSocket::UniquePtr serverSock(
1006 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1008 SSLHandshakeClient client(std::move(clientSock), true, false);
1009 clientCtx->loadTrustedCertificates(testCA);
1011 SSLHandshakeServer server(std::move(serverSock), true, true);
1015 EXPECT_TRUE(client.handshakeVerify_);
1016 EXPECT_TRUE(!client.handshakeSuccess_);
1017 EXPECT_TRUE(client.handshakeError_);
1018 EXPECT_TRUE(!server.handshakeVerify_);
1019 EXPECT_TRUE(!server.handshakeSuccess_);
1020 EXPECT_TRUE(server.handshakeError_);
1024 * Verify that the options in SSLContext can be overridden in
1025 * sslConnect/Accept.i.e specifying that no validation should be performed
1026 * allows an otherwise-invalid certificate to be accepted and doesn't fire
1027 * the validation callback.
1029 TEST(AsyncSSLSocketTest, OverrideSSLCtxDisableVerify) {
1030 EventBase eventBase;
1031 auto clientCtx = std::make_shared<SSLContext>();
1032 auto dfServerCtx = std::make_shared<SSLContext>();
1036 getctx(clientCtx, dfServerCtx);
1038 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1039 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1041 AsyncSSLSocket::UniquePtr clientSock(
1042 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1043 AsyncSSLSocket::UniquePtr serverSock(
1044 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1046 SSLHandshakeClientNoVerify client(std::move(clientSock), false, false);
1047 clientCtx->loadTrustedCertificates(testCA);
1049 SSLHandshakeServerNoVerify server(std::move(serverSock), false, false);
1053 EXPECT_TRUE(!client.handshakeVerify_);
1054 EXPECT_TRUE(client.handshakeSuccess_);
1055 EXPECT_TRUE(!client.handshakeError_);
1056 EXPECT_TRUE(!server.handshakeVerify_);
1057 EXPECT_TRUE(server.handshakeSuccess_);
1058 EXPECT_TRUE(!server.handshakeError_);
1062 * Verify that the options in SSLContext can be overridden in
1063 * sslConnect/Accept. Enable verification even if context says otherwise.
1064 * Test requireClientCert with client cert
1066 TEST(AsyncSSLSocketTest, OverrideSSLCtxEnableVerify) {
1067 EventBase eventBase;
1068 auto clientCtx = std::make_shared<SSLContext>();
1069 auto serverCtx = std::make_shared<SSLContext>();
1070 serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1071 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1072 serverCtx->loadPrivateKey(testKey);
1073 serverCtx->loadCertificate(testCert);
1074 serverCtx->loadTrustedCertificates(testCA);
1075 serverCtx->loadClientCAList(testCA);
1077 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1078 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1079 clientCtx->loadPrivateKey(testKey);
1080 clientCtx->loadCertificate(testCert);
1081 clientCtx->loadTrustedCertificates(testCA);
1086 AsyncSSLSocket::UniquePtr clientSock(
1087 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1088 AsyncSSLSocket::UniquePtr serverSock(
1089 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1091 SSLHandshakeClientDoVerify client(std::move(clientSock), true, true);
1092 SSLHandshakeServerDoVerify server(std::move(serverSock), true, true);
1096 EXPECT_TRUE(client.handshakeVerify_);
1097 EXPECT_TRUE(client.handshakeSuccess_);
1098 EXPECT_FALSE(client.handshakeError_);
1099 EXPECT_TRUE(server.handshakeVerify_);
1100 EXPECT_TRUE(server.handshakeSuccess_);
1101 EXPECT_FALSE(server.handshakeError_);
1105 * Verify that the client's verification callback is able to override
1106 * the preverification failure and allow a successful connection.
1108 TEST(AsyncSSLSocketTest, SSLHandshakeValidationOverride) {
1109 EventBase eventBase;
1110 auto clientCtx = std::make_shared<SSLContext>();
1111 auto dfServerCtx = std::make_shared<SSLContext>();
1115 getctx(clientCtx, dfServerCtx);
1117 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1118 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1120 AsyncSSLSocket::UniquePtr clientSock(
1121 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1122 AsyncSSLSocket::UniquePtr serverSock(
1123 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1125 SSLHandshakeClient client(std::move(clientSock), false, true);
1126 SSLHandshakeServer server(std::move(serverSock), true, true);
1130 EXPECT_TRUE(client.handshakeVerify_);
1131 EXPECT_TRUE(client.handshakeSuccess_);
1132 EXPECT_TRUE(!client.handshakeError_);
1133 EXPECT_TRUE(!server.handshakeVerify_);
1134 EXPECT_TRUE(server.handshakeSuccess_);
1135 EXPECT_TRUE(!server.handshakeError_);
1139 * Verify that specifying that no validation should be performed allows an
1140 * otherwise-invalid certificate to be accepted and doesn't fire the validation
1143 TEST(AsyncSSLSocketTest, SSLHandshakeValidationSkip) {
1144 EventBase eventBase;
1145 auto clientCtx = std::make_shared<SSLContext>();
1146 auto dfServerCtx = std::make_shared<SSLContext>();
1150 getctx(clientCtx, dfServerCtx);
1152 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1153 dfServerCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1155 AsyncSSLSocket::UniquePtr clientSock(
1156 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1157 AsyncSSLSocket::UniquePtr serverSock(
1158 new AsyncSSLSocket(dfServerCtx, &eventBase, fds[1], true));
1160 SSLHandshakeClient client(std::move(clientSock), false, false);
1161 SSLHandshakeServer server(std::move(serverSock), false, false);
1165 EXPECT_TRUE(!client.handshakeVerify_);
1166 EXPECT_TRUE(client.handshakeSuccess_);
1167 EXPECT_TRUE(!client.handshakeError_);
1168 EXPECT_TRUE(!server.handshakeVerify_);
1169 EXPECT_TRUE(server.handshakeSuccess_);
1170 EXPECT_TRUE(!server.handshakeError_);
1174 * Test requireClientCert with client cert
1176 TEST(AsyncSSLSocketTest, ClientCertHandshakeSuccess) {
1177 EventBase eventBase;
1178 auto clientCtx = std::make_shared<SSLContext>();
1179 auto serverCtx = std::make_shared<SSLContext>();
1180 serverCtx->setVerificationOption(
1181 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1182 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1183 serverCtx->loadPrivateKey(testKey);
1184 serverCtx->loadCertificate(testCert);
1185 serverCtx->loadTrustedCertificates(testCA);
1186 serverCtx->loadClientCAList(testCA);
1188 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
1189 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1190 clientCtx->loadPrivateKey(testKey);
1191 clientCtx->loadCertificate(testCert);
1192 clientCtx->loadTrustedCertificates(testCA);
1197 AsyncSSLSocket::UniquePtr clientSock(
1198 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1199 AsyncSSLSocket::UniquePtr serverSock(
1200 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1202 SSLHandshakeClient client(std::move(clientSock), true, true);
1203 SSLHandshakeServer server(std::move(serverSock), true, true);
1207 EXPECT_TRUE(client.handshakeVerify_);
1208 EXPECT_TRUE(client.handshakeSuccess_);
1209 EXPECT_FALSE(client.handshakeError_);
1210 EXPECT_TRUE(server.handshakeVerify_);
1211 EXPECT_TRUE(server.handshakeSuccess_);
1212 EXPECT_FALSE(server.handshakeError_);
1217 * Test requireClientCert with no client cert
1219 TEST(AsyncSSLSocketTest, NoClientCertHandshakeError) {
1220 EventBase eventBase;
1221 auto clientCtx = std::make_shared<SSLContext>();
1222 auto serverCtx = std::make_shared<SSLContext>();
1223 serverCtx->setVerificationOption(
1224 SSLContext::SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
1225 serverCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1226 serverCtx->loadPrivateKey(testKey);
1227 serverCtx->loadCertificate(testCert);
1228 serverCtx->loadTrustedCertificates(testCA);
1229 serverCtx->loadClientCAList(testCA);
1230 clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::NO_VERIFY);
1231 clientCtx->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1236 AsyncSSLSocket::UniquePtr clientSock(
1237 new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
1238 AsyncSSLSocket::UniquePtr serverSock(
1239 new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
1241 SSLHandshakeClient client(std::move(clientSock), false, false);
1242 SSLHandshakeServer server(std::move(serverSock), false, false);
1246 EXPECT_FALSE(server.handshakeVerify_);
1247 EXPECT_FALSE(server.handshakeSuccess_);
1248 EXPECT_TRUE(server.handshakeError_);
1251 TEST(AsyncSSLSocketTest, MinWriteSizeTest) {
1254 // Set up SSL context.
1255 auto sslContext = std::make_shared<SSLContext>();
1256 sslContext->ciphers("ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
1258 // create SSL socket
1259 AsyncSSLSocket::UniquePtr socket(new AsyncSSLSocket(sslContext, &eb));
1261 EXPECT_EQ(1500, socket->getMinWriteSize());
1263 socket->setMinWriteSize(0);
1264 EXPECT_EQ(0, socket->getMinWriteSize());
1265 socket->setMinWriteSize(50000);
1266 EXPECT_EQ(50000, socket->getMinWriteSize());
1269 class ReadCallbackTerminator : public ReadCallback {
1271 ReadCallbackTerminator(EventBase* base, WriteCallbackBase *wcb)
1275 // Do not write data back, terminate the loop.
1276 void readDataAvailable(size_t len) noexcept override {
1277 std::cerr << "readDataAvailable, len " << len << std::endl;
1279 currentBuffer.length = len;
1281 buffers.push_back(currentBuffer);
1282 currentBuffer.reset();
1283 state = STATE_SUCCEEDED;
1285 socket_->setReadCB(nullptr);
1286 base_->terminateLoopSoon();
1294 * Test a full unencrypted codepath
1296 TEST(AsyncSSLSocketTest, UnencryptedTest) {
1299 auto clientCtx = std::make_shared<folly::SSLContext>();
1300 auto serverCtx = std::make_shared<folly::SSLContext>();
1303 getctx(clientCtx, serverCtx);
1304 auto client = AsyncSSLSocket::newSocket(
1305 clientCtx, &base, fds[0], false, true);
1306 auto server = AsyncSSLSocket::newSocket(
1307 serverCtx, &base, fds[1], true, true);
1309 ReadCallbackTerminator readCallback(&base, nullptr);
1310 server->setReadCB(&readCallback);
1311 readCallback.setSocket(server);
1314 memset(buf, 'a', sizeof(buf));
1315 client->write(nullptr, buf, sizeof(buf));
1317 // Check that bytes are unencrypted
1319 EXPECT_EQ(1, recv(fds[1], &c, 1, MSG_PEEK));
1322 EventBaseAborter eba(&base, 3000);
1325 EXPECT_EQ(1, readCallback.buffers.size());
1326 EXPECT_EQ(AsyncSSLSocket::STATE_UNENCRYPTED, client->getSSLState());
1328 server->setReadCB(&readCallback);
1331 server->sslAccept(nullptr);
1332 client->sslConn(nullptr);
1334 // Do NOT wait for handshake, writing should be queued and happen after
1336 client->write(nullptr, buf, sizeof(buf));
1338 // Check that bytes are *not* unencrypted
1340 EXPECT_EQ(1, recv(fds[1], &c2, 1, MSG_PEEK));
1346 EXPECT_EQ(2, readCallback.buffers.size());
1347 EXPECT_EQ(AsyncSSLSocket::STATE_ESTABLISHED, client->getSSLState());
1352 ///////////////////////////////////////////////////////////////////////////
1353 // init_unit_test_suite
1354 ///////////////////////////////////////////////////////////////////////////
1356 struct Initializer {
1358 signal(SIGPIPE, SIG_IGN);
1361 Initializer initializer;