Compare commits
	
		
			1 Commits
		
	
	
		
			v7.6.5
			...
			feature/ma
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					84361c16a9 | 
@@ -1,16 +1,13 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
All changes to this project will be documented in this file.
 | 
					All changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [7.6.5] - 2019-12-24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
(cobra client) send a websocket ping every 30s to keep the connection opened
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## [7.6.4] - 2019-12-22
 | 
					## [7.6.4] - 2019-12-22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(client) error handling, quote url in error case when failing to parse one
 | 
					(client) error handling, quote url in error case when failing to parse one
 | 
				
			||||||
(ws) ws_cobra_publish: register callbacks before connecting
 | 
					(ws) ws_cobra_publish: register callbacks before connecting
 | 
				
			||||||
(doc) mention mbedtls in supported ssl server backend
 | 
					(doc) mention mbedtls in supported ssl server backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [7.6.3] - 2019-12-20
 | 
					## [7.6.3] - 2019-12-20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(tls) add a simple description of the TLS configuration routine for debugging
 | 
					(tls) add a simple description of the TLS configuration routine for debugging
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,6 @@ namespace ix
 | 
				
			|||||||
    PublishTrackerCallback CobraConnection::_publishTrackerCallback = nullptr;
 | 
					    PublishTrackerCallback CobraConnection::_publishTrackerCallback = nullptr;
 | 
				
			||||||
    constexpr size_t CobraConnection::kQueueMaxSize;
 | 
					    constexpr size_t CobraConnection::kQueueMaxSize;
 | 
				
			||||||
    constexpr CobraConnection::MsgId CobraConnection::kInvalidMsgId;
 | 
					    constexpr CobraConnection::MsgId CobraConnection::kInvalidMsgId;
 | 
				
			||||||
    constexpr int CobraConnection::kPingIntervalSecs;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CobraConnection::CobraConnection() :
 | 
					    CobraConnection::CobraConnection() :
 | 
				
			||||||
        _webSocket(new WebSocket()),
 | 
					        _webSocket(new WebSocket()),
 | 
				
			||||||
@@ -229,10 +228,6 @@ namespace ix
 | 
				
			|||||||
                    ss << "HTTP Status: "      << msg->errorInfo.http_status << std::endl;
 | 
					                    ss << "HTTP Status: "      << msg->errorInfo.http_status << std::endl;
 | 
				
			||||||
                    invokeErrorCallback(ss.str(), std::string());
 | 
					                    invokeErrorCallback(ss.str(), std::string());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (msg->type == ix::WebSocketMessageType::Pong)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    invokeEventCallback(ix::CobraConnection_EventType_Pong);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -265,7 +260,6 @@ namespace ix
 | 
				
			|||||||
        _webSocket->setUrl(url);
 | 
					        _webSocket->setUrl(url);
 | 
				
			||||||
        _webSocket->setPerMessageDeflateOptions(webSocketPerMessageDeflateOptions);
 | 
					        _webSocket->setPerMessageDeflateOptions(webSocketPerMessageDeflateOptions);
 | 
				
			||||||
        _webSocket->setTLSOptions(socketTLSOptions);
 | 
					        _webSocket->setTLSOptions(socketTLSOptions);
 | 
				
			||||||
        _webSocket->setPingInterval(kPingIntervalSecs);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //
 | 
					    //
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,8 +30,7 @@ namespace ix
 | 
				
			|||||||
        CobraConnection_EventType_Closed = 3,
 | 
					        CobraConnection_EventType_Closed = 3,
 | 
				
			||||||
        CobraConnection_EventType_Subscribed = 4,
 | 
					        CobraConnection_EventType_Subscribed = 4,
 | 
				
			||||||
        CobraConnection_EventType_UnSubscribed = 5,
 | 
					        CobraConnection_EventType_UnSubscribed = 5,
 | 
				
			||||||
        CobraConnection_EventType_Published = 6,
 | 
					        CobraConnection_EventType_Published = 6
 | 
				
			||||||
        CobraConnection_EventType_Pong = 7
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum CobraConnectionPublishMode
 | 
					    enum CobraConnectionPublishMode
 | 
				
			||||||
@@ -216,9 +215,6 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Each pdu sent should have an incremental unique id
 | 
					        // Each pdu sent should have an incremental unique id
 | 
				
			||||||
        std::atomic<uint64_t> _id;
 | 
					        std::atomic<uint64_t> _id;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Frequency at which we send a websocket ping to the backing cobra connection
 | 
					 | 
				
			||||||
        static constexpr int kPingIntervalSecs = 30;
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace ix
 | 
					} // namespace ix
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,10 +65,6 @@ namespace ix
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    ss << "Published message " << msgId << " acked";
 | 
					                    ss << "Published message " << msgId << " acked";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (eventType == ix::CobraConnection_EventType_Pong)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    ss << "Received websocket pong";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ix::IXCoreLogger::Log(ss.str().c_str());
 | 
					                ix::IXCoreLogger::Log(ss.str().c_str());
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,47 +24,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <Security/SecureTransport.h>
 | 
					#include <Security/SecureTransport.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ix
 | 
					namespace
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SocketAppleSSL::SocketAppleSSL(const SocketTLSOptions& tlsOptions, int fd)
 | 
					    OSStatus read_from_socket(SSLConnectionRef connection, void* data, size_t* len)
 | 
				
			||||||
        : Socket(fd)
 | 
					 | 
				
			||||||
        , _sslContext(nullptr)
 | 
					 | 
				
			||||||
        , _tlsOptions(tlsOptions)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        ;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SocketAppleSSL::~SocketAppleSSL()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        SocketAppleSSL::close();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    std::string SocketAppleSSL::getSSLErrorDescription(OSStatus status)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::string errMsg("Unknown SSL error.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CFErrorRef error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, status, NULL);
 | 
					 | 
				
			||||||
        if (error)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            CFStringRef message = CFErrorCopyDescription(error);
 | 
					 | 
				
			||||||
            if (message)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                char localBuffer[128];
 | 
					 | 
				
			||||||
                Boolean success;
 | 
					 | 
				
			||||||
                success = CFStringGetCString(message, localBuffer, 128, kCFStringEncodingUTF8);
 | 
					 | 
				
			||||||
                if (success)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    errMsg = localBuffer;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                CFRelease(message);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            CFRelease(error);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return errMsg;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    OSStatus SocketAppleSSL::readFromSocket(SSLConnectionRef connection, void* data, size_t* len)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int fd = (int) (long) connection;
 | 
					        int fd = (int) (long) connection;
 | 
				
			||||||
        if (fd < 0) return errSSLInternal;
 | 
					        if (fd < 0) return errSSLInternal;
 | 
				
			||||||
@@ -105,7 +67,7 @@ namespace ix
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OSStatus SocketAppleSSL::writeToSocket(SSLConnectionRef connection, const void* data, size_t* len)
 | 
					    OSStatus write_to_socket(SSLConnectionRef connection, const void* data, size_t* len)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int fd = (int) (long) connection;
 | 
					        int fd = (int) (long) connection;
 | 
				
			||||||
        if (fd < 0) return errSSLInternal;
 | 
					        if (fd < 0) return errSSLInternal;
 | 
				
			||||||
@@ -143,6 +105,145 @@ namespace ix
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string getSSLErrorDescription(OSStatus status)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::string errMsg("Unknown SSL error.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CFErrorRef error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, status, NULL);
 | 
				
			||||||
 | 
					        if (error)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            CFStringRef message = CFErrorCopyDescription(error);
 | 
				
			||||||
 | 
					            if (message)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                char localBuffer[128];
 | 
				
			||||||
 | 
					                Boolean success;
 | 
				
			||||||
 | 
					                success = CFStringGetCString(message, localBuffer, 128, kCFStringEncodingUTF8);
 | 
				
			||||||
 | 
					                if (success)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    errMsg = localBuffer;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                CFRelease(message);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            CFRelease(error);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return errMsg;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#undef CURL_BUILD_IOS
 | 
				
			||||||
 | 
					    OSStatus CopyIdentityFromPKCS12File(
 | 
				
			||||||
 | 
					        const char *cPath,
 | 
				
			||||||
 | 
					        const char *cPassword,
 | 
				
			||||||
 | 
					        SecIdentityRef *out_cert_and_key)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        OSStatus status = errSecItemNotFound;
 | 
				
			||||||
 | 
					        CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(
 | 
				
			||||||
 | 
					            NULL, (const UInt8 *)cPath, strlen(cPath), false);
 | 
				
			||||||
 | 
					        CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
 | 
				
			||||||
 | 
					            cPassword, kCFStringEncodingUTF8) : NULL;
 | 
				
			||||||
 | 
					        CFDataRef pkcs_data = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* We can import P12 files on iOS or OS X 10.7 or later: */
 | 
				
			||||||
 | 
					        /* These constants are documented as having first appeared in 10.6 but they
 | 
				
			||||||
 | 
					           raise linker errors when used on that cat for some reason. */
 | 
				
			||||||
 | 
					        if (CFURLCreateDataAndPropertiesFromResource(
 | 
				
			||||||
 | 
					            NULL, pkcs_url, &pkcs_data, NULL, NULL, &status)) {
 | 
				
			||||||
 | 
					            CFArrayRef items = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* On iOS SecPKCS12Import will never add the client certificate to the
 | 
				
			||||||
 | 
					             * Keychain.
 | 
				
			||||||
 | 
					             *
 | 
				
			||||||
 | 
					             * It gives us back a SecIdentityRef that we can use directly. */
 | 
				
			||||||
 | 
					#if CURL_BUILD_IOS
 | 
				
			||||||
 | 
					            const void *cKeys[] = {kSecImportExportPassphrase};
 | 
				
			||||||
 | 
					            const void *cValues[] = {password};
 | 
				
			||||||
 | 
					            CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
 | 
				
			||||||
 | 
					                    password ? 1L : 0L, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (options != NULL) {
 | 
				
			||||||
 | 
					                status = SecPKCS12Import(pkcs_data, options, &items);
 | 
				
			||||||
 | 
					                CFRelease(options);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* On macOS SecPKCS12Import will always add the client certificate to
 | 
				
			||||||
 | 
					             * the Keychain.
 | 
				
			||||||
 | 
					             *
 | 
				
			||||||
 | 
					             * As this doesn't match iOS, and apps may not want to see their client
 | 
				
			||||||
 | 
					             * certificate saved in the the user's keychain, we use SecItemImport
 | 
				
			||||||
 | 
					             * with a NULL keychain to avoid importing it.
 | 
				
			||||||
 | 
					             *
 | 
				
			||||||
 | 
					             * This returns a SecCertificateRef from which we can construct a
 | 
				
			||||||
 | 
					             * SecIdentityRef.
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            SecItemImportExportKeyParameters keyParams;
 | 
				
			||||||
 | 
					            SecExternalFormat inputFormat = kSecFormatPKCS12;
 | 
				
			||||||
 | 
					            SecExternalItemType inputType = kSecItemTypeCertificate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            memset(&keyParams, 0x00, sizeof(keyParams));
 | 
				
			||||||
 | 
					            keyParams.version    = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
 | 
				
			||||||
 | 
					            keyParams.passphrase = password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType,
 | 
				
			||||||
 | 
					                                   0, &keyParams, NULL, &items);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Extract the SecIdentityRef */
 | 
				
			||||||
 | 
					            if (status == errSecSuccess && items && CFArrayGetCount(items))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                CFIndex i, count;
 | 
				
			||||||
 | 
					                count = CFArrayGetCount(items);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for (i = 0; i < count; i++)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
 | 
				
			||||||
 | 
					                    CFTypeID  itemID = CFGetTypeID(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (itemID == CFDictionaryGetTypeID())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
 | 
				
			||||||
 | 
					                                (CFDictionaryRef) item,
 | 
				
			||||||
 | 
					                                kSecImportItemIdentity);
 | 
				
			||||||
 | 
					                        CFRetain(identity);
 | 
				
			||||||
 | 
					                        *out_cert_and_key = (SecIdentityRef) identity;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else if (itemID == SecCertificateGetTypeID())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        status = SecIdentityCreateWithCertificate(NULL,
 | 
				
			||||||
 | 
					                                (SecCertificateRef) item,
 | 
				
			||||||
 | 
					                                out_cert_and_key);
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (items) CFRelease(items);
 | 
				
			||||||
 | 
					            CFRelease(pkcs_data);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (password) CFRelease(password);
 | 
				
			||||||
 | 
					        CFRelease(pkcs_url);
 | 
				
			||||||
 | 
					        return status;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // anonymous namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SocketAppleSSL::SocketAppleSSL(const SocketTLSOptions& tlsOptions, int fd)
 | 
				
			||||||
 | 
					        : Socket(fd)
 | 
				
			||||||
 | 
					        , _sslContext(nullptr)
 | 
				
			||||||
 | 
					        , _tlsOptions(tlsOptions)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SocketAppleSSL::~SocketAppleSSL()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SocketAppleSSL::close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool SocketAppleSSL::accept(std::string& errMsg)
 | 
					    bool SocketAppleSSL::accept(std::string& errMsg)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -150,6 +251,63 @@ namespace ix
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool SocketAppleSSL::handleTLSOptions(std::string& errMsg)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        SecIdentityRef cert_and_key = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const char* ssl_cert = _tlsOptions.certFile.c_str();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        OSStatus err = CopyIdentityFromPKCS12File(ssl_cert, "foobar", &cert_and_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (err == noErr && cert_and_key)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            SecCertificateRef cert = NULL;
 | 
				
			||||||
 | 
					            CFTypeRef certs_c[1];
 | 
				
			||||||
 | 
					            CFArrayRef certs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            err = SecIdentityCopyCertificate(cert_and_key, &cert);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            certs_c[0] = cert_and_key;
 | 
				
			||||||
 | 
					            certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
 | 
				
			||||||
 | 
					                    &kCFTypeArrayCallBacks);
 | 
				
			||||||
 | 
					            err = SSLSetCertificate(_sslContext, certs);
 | 
				
			||||||
 | 
					            if (err != noErr)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                errMsg = "SSLSetCertificate failed";
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            switch(err) {
 | 
				
			||||||
 | 
					                case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
 | 
				
			||||||
 | 
					                    errMsg = "SSL: Incorrect password for the certificate \"%s\" "
 | 
				
			||||||
 | 
					                            "and its private key."; // , ssl_cert);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
 | 
				
			||||||
 | 
					                    errMsg = "SSL: Couldn't make sense of the data in the "
 | 
				
			||||||
 | 
					                            "certificate \"%s\" and its private key.";
 | 
				
			||||||
 | 
					                            ; // ssl_cert);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case -25260: /* errSecPassphraseRequired */
 | 
				
			||||||
 | 
					                    errMsg = "SSL The certificate \"%s\" requires a password.";
 | 
				
			||||||
 | 
					                            // ssl_cert);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case errSecItemNotFound:
 | 
				
			||||||
 | 
					                    errMsg = "SSL: Can't find the certificate \"%s\" and its private "
 | 
				
			||||||
 | 
					                            "key in the Keychain."; // , ssl_cert);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    errMsg = "SSL: Can't load the certificate \"%s\" and its private "
 | 
				
			||||||
 | 
					                            "key: OSStatus %d" ; // , ssl_cert, err);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // No wait support
 | 
					    // No wait support
 | 
				
			||||||
    bool SocketAppleSSL::connect(const std::string& host,
 | 
					    bool SocketAppleSSL::connect(const std::string& host,
 | 
				
			||||||
                                 int port,
 | 
					                                 int port,
 | 
				
			||||||
@@ -165,11 +323,13 @@ namespace ix
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            _sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
 | 
					            _sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SSLSetIOFuncs(_sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket);
 | 
					            SSLSetIOFuncs(_sslContext, read_from_socket, write_to_socket);
 | 
				
			||||||
            SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd);
 | 
					            SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd);
 | 
				
			||||||
            SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12);
 | 
					            SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12);
 | 
				
			||||||
            SSLSetPeerDomainName(_sslContext, host.c_str(), host.size());
 | 
					            SSLSetPeerDomainName(_sslContext, host.c_str(), host.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!handleTLSOptions(errMsg)) return false; // FIXME not calling close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (_tlsOptions.isPeerVerifyDisabled())
 | 
					            if (_tlsOptions.isPeerVerifyDisabled())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                Boolean option(1);
 | 
					                Boolean option(1);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,9 +34,7 @@ namespace ix
 | 
				
			|||||||
        virtual ssize_t recv(void* buffer, size_t length) final;
 | 
					        virtual ssize_t recv(void* buffer, size_t length) final;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        static std::string getSSLErrorDescription(OSStatus status);
 | 
					        bool handleTLSOptions(std::string& errMsg);
 | 
				
			||||||
        static OSStatus writeToSocket(SSLConnectionRef connection, const void* data, size_t* len);
 | 
					 | 
				
			||||||
        static OSStatus readFromSocket(SSLConnectionRef connection, void* data, size_t* len);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SSLContextRef _sslContext;
 | 
					        SSLContextRef _sslContext;
 | 
				
			||||||
        mutable std::mutex _mutex; // AppleSSL routines are not thread-safe
 | 
					        mutable std::mutex _mutex; // AppleSSL routines are not thread-safe
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IX_WEBSOCKET_VERSION "7.6.5"
 | 
					#define IX_WEBSOCKET_VERSION "7.6.4"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,10 +91,6 @@ namespace ix
 | 
				
			|||||||
                spdlog::info("Published message id {} acked", msgId);
 | 
					                spdlog::info("Published message id {} acked", msgId);
 | 
				
			||||||
                messageAcked = true;
 | 
					                messageAcked = true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (eventType == ix::CobraConnection_EventType_Pong)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                spdlog::info("Received websocket pong");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        conn.connect();
 | 
					        conn.connect();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,10 +100,6 @@ namespace ix
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    spdlog::error("Published message hacked: {}", msgId);
 | 
					                    spdlog::error("Published message hacked: {}", msgId);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (eventType == ix::CobraConnection_EventType_Pong)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    spdlog::info("Received websocket pong");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (true)
 | 
					        while (true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -245,10 +245,6 @@ namespace ix
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                spdlog::error("Published message hacked: {}", msgId);
 | 
					                spdlog::error("Published message hacked: {}", msgId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (eventType == ix::CobraConnection_EventType_Pong)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                spdlog::info("Received websocket pong");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (true)
 | 
					        while (true)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -160,10 +160,6 @@ namespace ix
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                spdlog::error("Published message hacked: {}", msgId);
 | 
					                spdlog::error("Published message hacked: {}", msgId);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (eventType == ix::CobraConnection_EventType_Pong)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                spdlog::info("Received websocket pong");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while (true)
 | 
					        while (true)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user