PubSub+ Messaging API For C  7.31.0.7
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ex/ios/examples/SecureSessionExample.m
/*
* Copyright 2009-2024 Solace Corporation. All rights reserved.
*/
#import "SecureSessionExample.h"
@implementation SecureSessionExample
- (id)initWithExampleInterface:(ExampleInterface *)exampleInterface {
self = [super initWithExampleInterface:exampleInterface];
// Set example name and description
self.name = @"SecureSession";
self.description =
@"Demonstrates how to establish a secure session and then "
@"subscribe and publish to a topic";
// Setup example parameters
[self.parameters parameterWithId:PARAMETER_HOST].value = @"tcps://";
[self.parameters removeParameter:PARAMETER_COMPRESSION];
[self.parameters addParameter:PARAMETER_NUM_MESSAGES];
[self.parameters addParameter:PARAMETER_SSL_NO_PROTOCOLS];
[self.parameters addParameter:PARAMETER_SSL_CIPHER_LIST];
[self.parameters addParameter:PARAMETER_SSL_CERTIFICATE_VALIDATION];
[self.parameters addParameter:PARAMETER_SSL_CERTIFICATE_DATE_VALIDATION];
[self.parameters addParameter:PARAMETER_SSL_TRUST_STORE_DIRECTORY];
[self.parameters addParameter:PARAMETER_SSL_COMMON_NAMES];
[self.parameters addParameter:PARAMETER_SSL_AUTHENTICATION_SCHEME];
[self.parameters addParameter:PARAMETER_SSL_CERTIFICATE];
[self.parameters addParameter:PARAMETER_SSL_PRIVATE_KEY];
[self.parameters addParameter:PARAMETER_SSL_PRIVATE_KEY_PASSWORD];
[self.parameters addParameter:PARAMETER_SSL_CONNECTION_DOWNGRADE_TO];
return self;
}
messageReceiveCallbackWithSession:
(solClient_opaqueSession_pt)opaqueSession_p
message:(solClient_opaqueMsg_pt)msg_p
userData:(void *)user_p {
// The message callback is invoked for each Direct message received by
// the Session. In this sample, the message is printed to the screen.
//
// Message callback code is executed within the API thread, which means that
// it should deal with the message quickly, or queue the message for further
// processing in another thread.
//
// Note: In other samples, a common message handler is used. However, to
// emphasize this programming paradigm, this sample directly includes the
// message receive callback.
solClient_log(SOLCLIENT_LOG_NOTICE, "Received message:\n");
char buffer[5000];
if ((rc = solClient_msg_dump(msg_p, buffer, 5000)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc errorString:"solClient_msg_dump()"];
}
}
- (void)run {
[super run];
// Context variables
// Session variables
// Session properties
const char *sessionProps[60];
int propIndex = 0;
// Message variables
solClient_opaqueMsg_pt msg_p = NULL;
int msgsSent = 0;
// Initialize the API; this must be done prior to first usage
[self handleErrorWithReturnCode:rc
errorString:"solClient_initialize()"];
goto notInitialized;
}
// Set up logging level and log example and API information
[self setLoggingLevel];
"SecureSessionExample.m (Copyright 2009-2024 Solace Corporation. All rights reserved.)\n");
[self logCCSMPVersion];
solClient_log(SOLCLIENT_LOG_INFO, "Creating solClient context");
// Create a context, and specify that the context thread be created
// automatically instead of having the application create its own
// context thread.
&contextFuncInfo, sizeof(contextFuncInfo))) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_context_create()"];
goto cleanup;
}
solClient_log(SOLCLIENT_LOG_INFO, "Creating solClient session.");
// Note: In other samples, common functions have been used to create
// and connect Sessions. However, for demonstration purposes, this sample
// includes Session creation and connection in line.
// Configure the Session function information.
sessionFuncInfo.rxMsgInfo.callback_p = messageReceiveCallback;
sessionFuncInfo.rxMsgInfo.user_p = self.nullBridge_p;
sessionFuncInfo.eventInfo.callback_p = eventCallback;
sessionFuncInfo.eventInfo.user_p = self.nullBridge_p;
{
// Configure the session's properties
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDir = [documentPaths objectAtIndex:0];
NSString *trustStoreDir = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:@"certificates.bundle/trustStores"];
propIndex = 0;
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_HOST;
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_HOST].value
cStringUsingEncoding:NSASCIIStringEncoding];
if ([(NSString *)[self.parameters
parameterWithId:PARAMETER_SSL_AUTHENTICATION_SCHEME].value
isEqualToString:@"Certificate"]) {
sessionProps[propIndex++] =
sessionProps[propIndex++] =
sessionProps[propIndex++] =
sessionProps[propIndex++] = [[documentDir
stringByAppendingPathComponent:
[self.parameters parameterWithId:PARAMETER_SSL_CERTIFICATE]
.value] cStringUsingEncoding:NSASCIIStringEncoding];
sessionProps[propIndex++] =
sessionProps[propIndex++] = [[documentDir
stringByAppendingPathComponent:
[self.parameters parameterWithId:PARAMETER_SSL_PRIVATE_KEY]
.value] cStringUsingEncoding:NSASCIIStringEncoding];
if (![[self.parameters parameterWithId:PARAMETER_SSL_PRIVATE_KEY]
.value isEqualToString:@""]) {
sessionProps[propIndex++] =
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_SSL_PRIVATE_KEY_PASSWORD]
.value cStringUsingEncoding:NSASCIIStringEncoding];
}
}
if (strlen([[self.parameters parameterWithId:PARAMETER_USERNAME].value
cStringUsingEncoding:NSASCIIStringEncoding]) > 0) {
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_USERNAME;
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_USERNAME].value
cStringUsingEncoding:NSASCIIStringEncoding];
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_PASSWORD;
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_PASSWORD].value
cStringUsingEncoding:NSASCIIStringEncoding];
}
if ([[self.parameters parameterWithId:PARAMETER_VPN].value
cStringUsingEncoding:NSASCIIStringEncoding][0]) {
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_VPN_NAME;
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_VPN].value
cStringUsingEncoding:NSASCIIStringEncoding];
}
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_RECONNECT_RETRIES;
sessionProps[propIndex++] = "3";
sessionProps[propIndex++] =
sessionProps[propIndex++] = "3";
// Note: Reapplying subscriptions allows Sessions to reconnect after
// failure and have all their subscriptions automatically restored. For
// Sessions with many subscriptions this can increase the amount of time
// required for a successful reconnect.
sessionProps[propIndex++] =
sessionProps[propIndex++] = SOLCLIENT_PROP_ENABLE_VAL;
if (![self.parameters
parameterWithId:PARAMETER_SSL_CERTIFICATE_VALIDATION]
.value.boolValue) {
sessionProps[propIndex++] =
sessionProps[propIndex++] = SOLCLIENT_PROP_DISABLE_VAL;
}
if (![self.parameters
parameterWithId:PARAMETER_SSL_CERTIFICATE_DATE_VALIDATION]
.value.boolValue) {
sessionProps[propIndex++] =
sessionProps[propIndex++] = SOLCLIENT_PROP_DISABLE_VAL;
}
if (![[self.parameters parameterWithId:PARAMETER_SSL_TRUST_STORE_DIRECTORY].value
isEqualToString:@""]) {
trustStoreDir = [documentDir stringByAppendingPathComponent:
[self.parameters parameterWithId:PARAMETER_SSL_TRUST_STORE_DIRECTORY].value];
}
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_SSL_TRUST_STORE_DIR;
sessionProps[propIndex++] = [trustStoreDir cStringUsingEncoding:NSASCIIStringEncoding];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:trustStoreDir]){
NSArray *listOfFiles = [fileManager contentsOfDirectoryAtPath:trustStoreDir error:nil];
if ([listOfFiles count] == 0) {
solClient_log(SOLCLIENT_LOG_NOTICE, "Couldn't find any trusted certificate in folder '%s'",
[trustStoreDir cStringUsingEncoding:NSASCIIStringEncoding]);
}
}
if (![[self.parameters parameterWithId:PARAMETER_SSL_CIPHER_LIST].value
isEqualToString:@""]) {
sessionProps[propIndex++] =
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_SSL_CIPHER_LIST]
.value cStringUsingEncoding:NSASCIIStringEncoding];
}
if (![[self.parameters parameterWithId:PARAMETER_SSL_COMMON_NAMES].value
isEqualToString:@""]) {
sessionProps[propIndex++] =
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_SSL_COMMON_NAMES]
.value cStringUsingEncoding:NSASCIIStringEncoding];
}
if (![[self.parameters parameterWithId:PARAMETER_SSL_NO_PROTOCOLS].value
isEqualToString:@""]) {
sessionProps[propIndex++] = SOLCLIENT_SESSION_PROP_SSL_EXCLUDED_PROTOCOLS;
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_SSL_NO_PROTOCOLS].value
cStringUsingEncoding:NSASCIIStringEncoding];
}
if (![[self.parameters parameterWithId:PARAMETER_SSL_CONNECTION_DOWNGRADE_TO].value
isEqualToString:@""]) {
sessionProps[propIndex++] =
sessionProps[propIndex++] =
[[self.parameters parameterWithId:PARAMETER_SSL_CONNECTION_DOWNGRADE_TO]
.value cStringUsingEncoding:NSASCIIStringEncoding];
}
sessionProps[propIndex] = NULL;
}
// Create the session
(char **)sessionProps, context_p, &session_p, &sessionFuncInfo,
sizeof(sessionFuncInfo))) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_create()"];
goto cleanup;
}
// Connect the session
if ((rc = solClient_session_connect(session_p)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_connect()"];
goto cleanup;
}
COMMON_MY_SAMPLE_TOPIC)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_topicSubscribe()"];
goto sessionConnected;
}
solClient_log(SOLCLIENT_LOG_INFO, "Publishing messages.\n");
for (msgsSent = 0;
msgsSent < [self.parameters parameterWithId:PARAMETER_NUM_MESSAGES]
.value.integerValue &&
!self.requestCancel;
++msgsSent) {
// Allocate memory for the message that is to be sent
if ((rc = solClient_msg_alloc(&msg_p)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_alloc()"];
goto sessionConnected;
}
// Set the message delivery mode
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_setDeliveryMode()"];
goto freeMessage;
}
// Set the destination
destination.dest = COMMON_MY_SAMPLE_TOPIC;
msg_p, &destination, sizeof(destination))) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_setDestination()"];
goto freeMessage;
}
// Add some content to the message
msg_p, COMMON_ATTACHMENT_TEXT,
(solClient_uint32_t)strlen(COMMON_ATTACHMENT_TEXT))) !=
[self handleErrorWithReturnCode:
rc errorString:"solClient_msg_setBinaryAttachment()"];
goto freeMessage;
}
// Send the message
if ((rc = solClient_session_sendMsg(session_p, msg_p)) !=
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_sendMsg()"];
goto freeMessage;
}
freeMessage:
if ((rc = solClient_msg_free(&msg_p)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_msg_free()"];
goto sessionConnected;
}
// Wait one second between sending messages. This provides time for
// the final message to be received.
[NSThread sleepForTimeInterval:1];
}
COMMON_MY_SAMPLE_TOPIC)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_topicSubscribe()"];
goto sessionConnected;
}
sessionConnected:
// Disconnect the session
if ((rc = solClient_session_disconnect(session_p)) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc
errorString:"solClient_session_disconnect()"];
}
cleanup:
// Cleanup solclient
if ((rc = solClient_cleanup()) != SOLCLIENT_OK) {
[self handleErrorWithReturnCode:rc errorString:"solClient_cleanup()"];
}
notInitialized:
[self cleanup];
}
@end