Compare commits
8 Commits
v7.6.3
...
feature/ma
Author | SHA1 | Date | |
---|---|---|---|
|
8192da790f | ||
|
33e7271b85 | ||
|
d72e5e70f6 | ||
|
e2c5f751bd | ||
|
351b86e266 | ||
|
d0cbff4f4e | ||
|
cbfc9b9f94 | ||
|
ca816d801f |
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
All changes to this project will be documented in this file.
|
||||
|
||||
## [7.6.4] - 2019-12-22
|
||||
|
||||
(client) error handling, quote url in error case when failing to parse one
|
||||
(ws) ws_cobra_publish: register callbacks before connecting
|
||||
(doc) mention mbedtls in supported ssl server backend
|
||||
|
||||
|
||||
## [7.6.3] - 2019-12-20
|
||||
|
||||
|
@@ -247,7 +247,7 @@ Options:
|
||||
|
||||
[cobra](https://github.com/machinezone/cobra) is a real time messenging server. ws has several sub-command to interact with cobra. There is also a minimal cobra compatible server named snake available.
|
||||
|
||||
Below are examples on running a snake server and clients with TLS enabled (the server only works with the OpenSSL backend for now).
|
||||
Below are examples on running a snake server and clients with TLS enabled (the server only works with the OpenSSL and the Mbed TLS backend for now).
|
||||
|
||||
First, generate certificates.
|
||||
|
||||
@@ -366,4 +366,4 @@ $ ws cobra_publish --endpoint wss://127.0.0.1:8765 --appkey FC2F10139A2BAc53BB72
|
||||
[2019-12-19 20:46:42.659] [info] Published message id 3 acked
|
||||
```
|
||||
|
||||
To use OpenSSL on macOS, compile with `make ws_openssl`. First you will have to install OpenSSL libraries, which can be done with Homebrew.
|
||||
To use OpenSSL on macOS, compile with `make ws_openssl`. First you will have to install OpenSSL libraries, which can be done with Homebrew. Use `make ws_mbedtls` accordingly to use MbedTLS.
|
||||
|
@@ -24,9 +24,47 @@
|
||||
|
||||
#include <Security/SecureTransport.h>
|
||||
|
||||
namespace
|
||||
namespace ix
|
||||
{
|
||||
OSStatus read_from_socket(SSLConnectionRef connection, void* data, size_t* len)
|
||||
SocketAppleSSL::SocketAppleSSL(const SocketTLSOptions& tlsOptions, int fd)
|
||||
: 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;
|
||||
if (fd < 0) return errSSLInternal;
|
||||
@@ -67,7 +105,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus write_to_socket(SSLConnectionRef connection, const void* data, size_t* len)
|
||||
OSStatus SocketAppleSSL::writeToSocket(SSLConnectionRef connection, const void* data, size_t* len)
|
||||
{
|
||||
int fd = (int) (long) connection;
|
||||
if (fd < 0) return errSSLInternal;
|
||||
@@ -105,52 +143,55 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
} // 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)
|
||||
{
|
||||
errMsg = "TLS not supported yet in server mode with apple ssl backend";
|
||||
return false;
|
||||
OSStatus status;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
|
||||
_sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType);
|
||||
|
||||
SSLSetIOFuncs(_sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket);
|
||||
SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd);
|
||||
SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12);
|
||||
|
||||
if (_tlsOptions.isPeerVerifyDisabled())
|
||||
{
|
||||
Boolean option(1);
|
||||
SSLSetSessionOption(_sslContext, kSSLSessionOptionBreakOnServerAuth, option);
|
||||
|
||||
do
|
||||
{
|
||||
status = SSLHandshake(_sslContext);
|
||||
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
|
||||
|
||||
if (status == errSSLServerAuthCompleted)
|
||||
{
|
||||
// proceed with the handshake
|
||||
do
|
||||
{
|
||||
status = SSLHandshake(_sslContext);
|
||||
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
status = SSLHandshake(_sslContext);
|
||||
} while (errSSLWouldBlock == status || errSSLServerAuthCompleted == status);
|
||||
}
|
||||
}
|
||||
|
||||
if (noErr != status)
|
||||
{
|
||||
errMsg = getSSLErrorDescription(status);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// No wait support
|
||||
@@ -168,7 +209,7 @@ namespace ix
|
||||
|
||||
_sslContext = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType);
|
||||
|
||||
SSLSetIOFuncs(_sslContext, read_from_socket, write_to_socket);
|
||||
SSLSetIOFuncs(_sslContext, SocketAppleSSL::readFromSocket, SocketAppleSSL::writeToSocket);
|
||||
SSLSetConnection(_sslContext, (SSLConnectionRef)(long) _sockfd);
|
||||
SSLSetProtocolVersionMin(_sslContext, kTLSProtocol12);
|
||||
SSLSetPeerDomainName(_sslContext, host.c_str(), host.size());
|
||||
|
@@ -34,6 +34,10 @@ namespace ix
|
||||
virtual ssize_t recv(void* buffer, size_t length) final;
|
||||
|
||||
private:
|
||||
static std::string getSSLErrorDescription(OSStatus status);
|
||||
static OSStatus writeToSocket(SSLConnectionRef connection, const void* data, size_t* len);
|
||||
static OSStatus readFromSocket(SSLConnectionRef connection, void* data, size_t* len);
|
||||
|
||||
SSLContextRef _sslContext;
|
||||
mutable std::mutex _mutex; // AppleSSL routines are not thread-safe
|
||||
|
||||
|
@@ -81,6 +81,7 @@ namespace ix
|
||||
ss << " keyFile = " << keyFile << std::endl;
|
||||
ss << " caFile = " << caFile << std::endl;
|
||||
ss << " ciphers = " << ciphers << std::endl;
|
||||
ss << " ciphers = " << ciphers << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
} // namespace ix
|
||||
|
@@ -144,7 +144,9 @@ namespace ix
|
||||
|
||||
if (!UrlParser::parse(url, protocol, host, path, query, port))
|
||||
{
|
||||
return WebSocketInitResult(false, 0, std::string("Could not parse URL ") + url);
|
||||
std::stringstream ss;
|
||||
ss << "Could not parse url: '" << url << "'";
|
||||
return WebSocketInitResult(false, 0, ss.str());
|
||||
}
|
||||
|
||||
std::string errorMsg;
|
||||
|
@@ -6,4 +6,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define IX_WEBSOCKET_VERSION "7.6.3"
|
||||
#define IX_WEBSOCKET_VERSION "7.6.4"
|
||||
|
@@ -43,7 +43,6 @@ namespace ix
|
||||
rolesecret,
|
||||
ix::WebSocketPerMessageDeflateOptions(true),
|
||||
tlsOptions);
|
||||
conn.connect();
|
||||
|
||||
// Display incoming messages
|
||||
std::atomic<bool> authenticated(false);
|
||||
@@ -94,6 +93,8 @@ namespace ix
|
||||
}
|
||||
});
|
||||
|
||||
conn.connect();
|
||||
|
||||
while (!authenticated)
|
||||
;
|
||||
while (!messageAcked)
|
||||
|
Reference in New Issue
Block a user