#include "os.h"
#include "common.h"
typedef enum _authenticationScheme {
_AUTHENTICATION_SCHEME_BASIC,
_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE,
} _authenticationScheme_t;
struct options
{
char targetHost[256];
int numMsgsToSend;
char *sslTrustStoreDir_p;
char *sslCommonNames_p;
char *sslExcludedProtocols_p;
char *sslCipherList_p;
BOOL isCertificateVarificationOff;
BOOL isCertificateDateVarificationOff;
char *sslCertFile_p;
char *sslKeyFile_p;
char *sslKeyPasswd_p;
_authenticationScheme_t authScheme;
char *sslDowngrade_p;
};
#define USAGE_PARAMS \
"\t-c, --cip=tcps:ip[:port] protocol, IP and port of the messaging appliance (e.g. --cip=tcps:192.168.160.101).\n"\
"\t-u, --cu=[user][@vpn] Client username and Mesage VPN name. The VPN name is optional and\n"\
"\t only used in a Solace messaging appliance running SolOS-TR.\n"\
"\t-p, --cp=password Client password.\n"\
"\t-T --dir=directory Full directory path name where the trusted certificates are.\n"\
"\t It is required if the certificate verification is enabled.\n" \
"\t-N --cn=commonnames List of comma separated trusted common names.\n"\
"\t-C --cipher=ciphers List of comma separated cipher suites.\n"\
"\t-P --prot=list of excluded SSL protocols, separated by comma.\n"\
"\t-E --cert=certFile Client certificate file name.\n"\
"\t-Y --key=keyFile Client certificate private key file name.\n"\
"\t-W --passwd=password Encrypted client certificate private key file password.\n"\
"\t-k --auth=authentication scheme: 0=basic, 1=client-certificate.\n"\
"\t-i certificate verification is disabled (enabled by default).\n"\
"\t-j certificate date verification is disabled (enabled by default).\n"\
"\t-l, --log=loglevel API and application logging level (debug, info, notice, warn, error, critical).\n" \
"\t-d -downgr=PLAIN_TEXT Downgrade SSL connection to 'PLAIN_TEXT' after client authentication.\n"
static void
printUsage ( )
{
printf ( "\nUsage: secureSession PARAMETERS\n\n" "Where PARAMETERS are: \n" USAGE_PARAMS );
}
{
printf ( "Received message:\n" );
common_handleError ( rc, "solClient_msg_dump()" );
}
printf ( "\n" );
}
static int
parseCommandOptions ( int argc, charPtr32 *argv, struct options *opt )
{
static char *optstring = "c:l:n:p:u:P:C:N:T:ijE:Y:W:k:d:";
static struct option longopts[] = {
{"cip", 1, NULL, 'c'},
{"cu", 1, NULL, 'u'},
{"mn", 1, NULL, 'n'},
{"log", 1, NULL, 'l'},
{"cp", 1, NULL, 'p'},
{"dir", 1, NULL, 'T'},
{"cn", 1, NULL, 'N'},
{"cipher", 1, NULL, 'C'},
{"prot", 1, NULL, 'P'},
{"cert", 1, NULL, 'E'},
{"key", 1, NULL, 'Y'},
{"passwd", 1, NULL, 'W'},
{"auth", 1, NULL, 'k'},
{"downgr", 1, NULL, 'd'},
{0, 0, 0, 0}
};
int c;
int rc = 1;
char *end_p;
size_t strLen;
char *begin_p;
charPtr *argVOS;
opt->username[0] = ( char ) 0;
opt->password[0] = ( char ) 0;
opt->vpn[0] = ( char ) 0;
opt->targetHost[0] = ( char ) 0;
opt->numMsgsToSend = 10;
opt->sslTrustStoreDir_p = NULL;
opt->sslCommonNames_p = NULL;
opt->sslExcludedProtocols_p = NULL;
opt->sslCipherList_p = NULL;
opt->isCertificateVarificationOff = FALSE;
opt->isCertificateDateVarificationOff = FALSE;
opt->sslCertFile_p = NULL;
opt->sslKeyFile_p = NULL;
opt->sslKeyPasswd_p = NULL;
opt->authScheme = _AUTHENTICATION_SCHEME_BASIC;
opt->sslDowngrade_p = NULL;
INIT_OS_ARGS(argc, argv, argVOS);
while ( ( c = getopt_long ( argc, argVOS, optstring, longopts, NULL ) ) != -1 ) {
switch ( c ) {
case 'c':
strncpy ( opt->targetHost, optarg, sizeof ( opt->targetHost ) );
begin_p = opt->targetHost;
strLen = (int)strlen(begin_p);
end_p = begin_p + strLen;
while (begin_p < end_p) {
if ((strncasecmp( begin_p, "tcps:", 5) != 0) &&
(strncasecmp( begin_p, "wss:", 4) != 0) &&
(strncasecmp( begin_p, "https:", 6) != 0)) {
printf("%s: support secure transport protocols only\n", opt->targetHost);
return 0;
}
begin_p = strchr(begin_p, ',');
if (begin_p == NULL) {
break;
}
begin_p++;
}
break;
case 'l':
if ( strcasecmp ( optarg, "debug" ) == 0 ) {
} else if ( strcasecmp ( optarg, "info" ) == 0 ) {
} else if ( strcasecmp ( optarg, "notice" ) == 0 ) {
} else if ( strcasecmp ( optarg, "warn" ) == 0 ) {
} else if ( strcasecmp ( optarg, "error" ) == 0 ) {
} else if ( strcasecmp ( optarg, "critical" ) == 0 ) {
} else {
rc = 0;
}
}
break;
case 'n':
opt->numMsgsToSend = atoi ( optarg );
if ( opt->numMsgsToSend <= 0 )
rc = 0;
break;
case 'u':
common_parseUsernameAndVpn ( optarg,
opt->username,
sizeof ( opt->username ), opt->vpn, sizeof ( opt->vpn ) );
break;
case 'p':
strncpy ( opt->password, optarg, sizeof ( opt->password ) );
break;
case 'T':
strLen = strlen(optarg);
opt->sslTrustStoreDir_p = (char *)malloc(strLen+1);
if (opt->sslTrustStoreDir_p == NULL) {
exit (-1);
}
strncpy ( opt->sslTrustStoreDir_p, optarg, strLen +1 );
break;
case 'N':
strLen = strlen(optarg);
opt->sslCommonNames_p = (char *)malloc(strLen+1);
if (opt->sslCommonNames_p == NULL) {
exit (-1);
}
strncpy ( opt->sslCommonNames_p, optarg, strLen +1 );
break;
case 'C':
strLen = strlen(optarg);
opt->sslCipherList_p = (char *)malloc(strLen+1);
if (opt->sslCipherList_p == NULL) {
exit (-1);
}
strncpy ( opt->sslCipherList_p, optarg, strLen +1 );
break;
case 'P':
strLen = strlen(optarg);
opt->sslExcludedProtocols_p = (char *)malloc(strLen+1);
if (opt->sslExcludedProtocols_p == NULL) {
exit (-1);
}
strncpy ( opt->sslExcludedProtocols_p, optarg, strLen +1 );
break;
case 'i':
opt->isCertificateVarificationOff = TRUE;
break;
case 'j':
opt->isCertificateDateVarificationOff = TRUE;
break;
case 'E':
strLen = strlen(optarg);
opt->sslCertFile_p = (char *)malloc(strLen+1);
if (opt->sslCertFile_p == NULL) {
exit (-1);
}
strncpy ( opt->sslCertFile_p, optarg, strLen +1 );
break;
case 'Y':
strLen = strlen(optarg);
opt->sslKeyFile_p = (char *)malloc(strLen+1);
if (opt->sslKeyFile_p == NULL) {
exit (-1);
}
strncpy ( opt->sslKeyFile_p, optarg, strLen +1 );
break;
case 'W':
strLen = strlen(optarg);
opt->sslKeyPasswd_p = (char *)malloc(strLen+1);
if (opt->sslKeyPasswd_p == NULL) {
exit (-1);
}
strncpy ( opt->sslKeyPasswd_p, optarg, strLen +1 );
break;
case 'k':
opt->authScheme = ( _authenticationScheme_t ) strtol ( optarg, &end_p, 0 );
if ( ( opt->authScheme > _AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE) || ( *end_p != ( char ) 0 ) ) {
if ( strcasecmp ( optarg, "basic" ) == 0 ) {
opt->authScheme = _AUTHENTICATION_SCHEME_BASIC;
} else if ( strcasecmp ( optarg, "client-certificate" ) == 0 ) {
opt->authScheme = _AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE;
} else {
rc = 0;
}
}
break;
case 'd':
strLen = strlen(optarg);
opt->sslDowngrade_p = (char *)malloc(strLen+1);
if (opt->sslDowngrade_p == NULL) {
exit (-1);
}
strncpy ( opt->sslDowngrade_p, optarg, strLen +1 );
break;
default:
rc = 0;
break;
}
}
if ((!opt->authScheme == _AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE) &&
(strlen(opt->username) == 0)) {
printf ( "Missing required parameter '--cu'\n" );
rc = 0;
}
if ((opt->isCertificateVarificationOff == FALSE) &&
(opt->sslTrustStoreDir_p == NULL)) {
printf ( "Missing required parameter '--dir'\n" );
rc = 0;
}
if ((opt->authScheme == _AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE) &&
((opt->sslKeyFile_p == NULL) ||
(opt->sslCertFile_p == NULL))) {
printf ( "Missing required parameters '--cert' and/or '--key'\n" );
rc = 0;
}
FREE_OS_ARGS
return ( rc );
}
int
main ( int argc, char *argv[] )
{
struct options commandOpts;
const char *sessionProps[60];
int propIndex = 0;
int msgsSent = 0;
printf ( "\nsecureSession.c (Copyright 2009-2024 Solace Corporation. All rights reserved.)\n" );
if ( parseCommandOptions ( argc, argv, &commandOpts ) == 0 ) {
goto printUsage;
}
common_handleError ( rc, "solClient_initialize()" );
goto notInitialized;
}
common_printCCSMPversion ( );
&context_p, &contextFuncInfo,
sizeof ( contextFuncInfo ) ) ) !=
SOLCLIENT_OK ) {
common_handleError ( rc, "solClient_context_create()" );
goto cleanup;
}
propIndex = 0;
if ( commandOpts.targetHost[0] != (char) 0 ) {
sessionProps[propIndex++] = commandOpts.targetHost;
}
if (commandOpts.authScheme == _AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE) {
sessionProps[propIndex++] = commandOpts.sslCertFile_p;
sessionProps[propIndex++] = commandOpts.sslKeyFile_p;
if (commandOpts.sslKeyPasswd_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslKeyPasswd_p;
}
}
if (strlen(commandOpts.username)>0) {
sessionProps[propIndex++] = commandOpts.username;
sessionProps[propIndex++] = commandOpts.password;
}
if ( commandOpts.vpn[0] ) {
sessionProps[propIndex++] = commandOpts.vpn;
}
sessionProps[propIndex++] = "3";
sessionProps[propIndex++] = "3";
if (commandOpts.isCertificateVarificationOff == TRUE) {
}
if (commandOpts.isCertificateDateVarificationOff == TRUE) {
}
if (commandOpts.sslTrustStoreDir_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslTrustStoreDir_p;
}
if (commandOpts.sslCipherList_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslCipherList_p;
}
if (commandOpts.sslCommonNames_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslCommonNames_p;
}
if (commandOpts.sslExcludedProtocols_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslExcludedProtocols_p;
}
if (commandOpts.sslDowngrade_p != NULL) {
sessionProps[propIndex++] = commandOpts.sslDowngrade_p;
}
sessionProps[propIndex] = NULL;
context_p,
&session_p, &sessionFuncInfo,
sizeof ( sessionFuncInfo ) ) ) !=
SOLCLIENT_OK ) {
common_handleError ( rc, "solClient_session_create()" );
goto cleanup;
}
common_handleError ( rc, "solClient_session_connect()" );
goto cleanup;
}
common_handleError ( rc, "solClient_session_topicSubscribe()" );
goto sessionConnected;
}
for ( msgsSent = 0; msgsSent < commandOpts.numMsgsToSend; ++msgsSent ) {
common_handleError ( rc, "solClient_msg_alloc()" );
goto sessionConnected;
}
common_handleError ( rc, "solClient_msg_setDeliveryMode()" );
goto freeMessage;
}
destination.
dest = COMMON_MY_SAMPLE_TOPIC;
common_handleError ( rc, "solClient_msg_setDestination()" );
goto freeMessage;
}
COMMON_ATTACHMENT_TEXT,
( solClient_uint32_t ) strlen ( COMMON_ATTACHMENT_TEXT ) ) ) !=
common_handleError ( rc, "solClient_msg_setBinaryAttachment()" );
goto freeMessage;
}
common_handleError ( rc, "solClient_session_sendMsg()" );
goto freeMessage;
}
freeMessage:
common_handleError ( rc, "solClient_msg_free()" );
goto sessionConnected;
}
sleepInSec ( 1 );
}
common_handleError ( rc, "solClient_session_topicSubscribe()" );
goto sessionConnected;
}
sessionConnected:
common_handleError ( rc, "solClient_session_disconnect()" );
}
cleanup:
common_handleError ( rc, "solClient_cleanup()" );
}
goto notInitialized;
printUsage:
printUsage ( );
notInitialized:
if (commandOpts.sslTrustStoreDir_p != NULL) {
free((void *)commandOpts.sslTrustStoreDir_p);
}
if (commandOpts.sslCipherList_p != NULL) {
free((void *)commandOpts.sslCipherList_p);
}
if (commandOpts.sslCommonNames_p != NULL) {
free((void *)commandOpts.sslCommonNames_p);
}
if (commandOpts.sslExcludedProtocols_p != NULL) {
free((void *)commandOpts.sslExcludedProtocols_p);
}
if (commandOpts.sslCertFile_p != NULL) {
free((void *)commandOpts.sslCertFile_p);
}
if (commandOpts.sslKeyFile_p != NULL) {
free((void *)commandOpts.sslKeyFile_p);
}
if (commandOpts.sslKeyPasswd_p != NULL) {
free((void *)commandOpts.sslKeyPasswd_p);
}
if (commandOpts.sslDowngrade_p != NULL) {
free((void *)commandOpts.sslDowngrade_p);
}
return 0;
}