[Patch 1.1 1/1] Mama: Add support for Citihub permission server abstraction API


David Sewell
 

This patch adds support for the Citihub permission server abstraction API which provides integration with multiple 3rd party entitlement systems (e.g. Thomson Reuters DACS, Bloomberg). This new feature will allow OpenMAMA API to integrate with existing permission systems, making the adoption of OpenMAMA easier and more attractive for large enterprises with existing market data systems and compliance control systems.

The change does not have any direct impact on the rest of the OpenMAMA API, all code changes are encompassed within the #ifdef WITH_CHUB_PERMSVR ... #endif pre-processor directives which is enabled with the build configuration option '--with-chub-permsvr=<path to libPermSvr>'. No existing APIs have been modified, deprecated or removed in this patch.

The inclusion of this new feature was discussed on the mailing lists here: http://lists.openmama.org/pipermail/openmama-dev/2011-December/000011.html.

Documentation for Citihub's Permission Server software can be downloaded from the following URLs:
Overview
http://server1.citihub.com/downloads/Citihub%20Permission%20Server%20Brochure%20v1.2.pdf
API Developers Guide
http://server1.citihub.com/downloads/libPermSvr_APIGuide_v17_3.pdf
Permission Server Admin Guide
http://server1.citihub.com/downloads/PermSvr_Installation_and_Admin_Guide_17_2.pdf

Instructions for testing Citihub Permission Server integration with OpenMAMA

1. Download Citihub libPermSvr library from the following URL (built on Ubuntu 11.10 32bit but should be portable and Citihub can provide binaries for most popular versions of Linux, Solaris and Windows)
http://server1.citihub.com/downloads/libPermSvr_12.0.17.7-beta-r205.linux.tar.gz

2. Download demo Citihub Permission Server from one of the following URLs (built on Ubuntu 11.10 32bit but should be portable and Citihub can provide binaries for most popular versions of Linux and Solaris)
- With file based permissions (used for testing only)
http://server1.citihub.com/downloads/PermSvr_12.0.17.4-beta-demo-fileonly-r278.linux.tar.gz

- With support for Thomason Reuters DACS (requires RFA and DACS software and licenses which are not included)
http://server1.citihub.com/downloads/PermSvr_12.0.17.4-beta-demo-withDACS-r278.linux.tar.gz

3. Uncompress the Permission Server software
tar xzvf PermSvr_12.0.17.4-beta-demo-fileonly-r278.linux.tar.gz
./PermSvr_12.0.17.4-beta-demo-fileonly-r278
:

4. Configure and start Permission Server
cd PermSvr_12.0.17.4-beta-demo-fileonly-r278
vi etc/perm_file.usr (optional configure test userid's and permissions)
./script/do_PermSvr start
tail -200 ./log/log_PermSvr.log
PermSvr Admin GUI - http://<hostname>:7141

5. Uncompress the libPermSvr software package
tar xzvf libPermSvr_12.0.17.7-beta-r205.linux.tar.gz
./libPermSvr_12.0.17.7-beta-r205
:

6. Build OpenMAMA with libPermSvr enabled
cd <root of OpenMama source code>
patch -p1 <patch file given below>
generateBuildFiles.sh
./configure --with-chub-permsvr=<path to libPermSvr software from step 5. above>
make
make install
7. Configure Permission Server host and port details in the mama.entitlement.servers parameter, see full list of libPermSvr configuration parameters below.

8. Run OpenMAMA test client, e.g.

cd /opt/openmama
./bin/mamasubscriberc -m avis
Starting Subscriber with:
topic: MAMA_TOPIC
transport: sub
2011-12-09 13:45:58:
********************************************************************************
Warning: This is a developer release and has only undergone basic sanity checks.
It is for testing only and should not be used in a production environment
**********************************************************************************
2011-12-09 13:45:58: openmama DEVRELEASE.. (1.2.4) (entitled libPermSvr)
2011-12-09 13:45:58: libPermSvr Build 17.7 r204 Dec 4 2011 12:40:31 (c) Citihub Ltd.
[2011-12-09 13:45:58.754779] libPermSvr Build 17.7 r204 Dec 4 2011 12:40:31 (c) Citihub Ltd.
[2011-12-09 13:45:58.755084] Logging enabled: stdout [level 2]
[2011-12-09 13:45:58.755262] [INFO] CHUB_GetLibAttr()
2011-12-09 13:45:58: Entitlement position ID : testuser
2011-12-09 13:45:58: Attempting to connect to entitlement server : testhost4:9990,testhost1:9990
[2011-12-09 13:45:58.756147] [INFO] CHUB_InitializeSingleUser( testhost4:9990,testhost1:9990, testuser )
[2011-12-09 13:45:58.756326] [INFO] CHUB_Initialize( testhost4:9990,testhost1:9990 )
[2011-12-09 13:45:58.756903] [INFO] CHUB_SetLibAttr()
[2011-12-09 13:45:58.757120] [INFO] CHUB_Connect()
[2011-12-09 13:45:58.758309] [WARNING] testhost4:9990 connected
[2011-12-09 13:45:58.758588] [INFO] SO_RCVBUF : Grow from 87552 to 262142
[2011-12-09 13:45:58.759924] [INFO] CBK CONNECT : testhost4:9990
[2011-12-09 13:45:58.760145] [INFO] CHUB_WaitOnConnect( 3 )
[2011-12-09 13:45:58.761579] [INFO] CHUB_WaitOnUserReady( testuser, 2 )
[2011-12-09 13:45:58.859171] [INFO] IOCTL : CPE=0; SFN=1
[2011-12-09 13:45:58.859640] [INFO] LOGIN : testuser; ID=158.760650-a8c085e9; PING=60
[2011-12-09 13:45:58.860141] [INFO] CBK LOGIN : testuser
[2011-12-09 13:45:58.863638] [INFO] GETALL : testuser ID=158.760650-a8c085e9; TTL=43200; STATE=READY
[2011-12-09 13:45:58.865290] [INFO] CBK GETALL testuser; nSBE=12; nCBE=3; STATE=READY
2011-12-09 13:45:58: Creating transport: [sub]
2011-12-09 13:45:58: Setting mama.entitlement.transport.sub.source=WOMBAT
2011-12-09 13:45:58: initializing Avis transport: sub
2011-12-09 13:45:58: sub: Using default preinitial strategy: ON_GAP
[2011-12-09 13:45:58.879395] [INFO] CHUB_IsPermissioned( testuser,WOMBAT,MAMA_TOPIC,0 ) = PERMIT
2011-12-09 13:45:58: setupBasic(): MAMA_TOPIC: subscription (0x8276018)
mamasubscriberc: Created inbound subscription.
mamasubscriberc: Recieved msg.
10002 10002 STRING MAMA_TOPIC
10 10 I32 290
2 2 I32 0

Citihub Permission Server configuration parameters in mama.properties:

mama.entitlement.servers = <host:port>,<host:port>
mama.entitlement.altposid = <userid>+<appid>+<ipaddr/net>:<entitlement_system>+<siteid> Override below parameters e.g. testuser+256+127.0.0.1/net:DACS+DACS
mama.entitlement.altuserid = <userid> defaults to runtime user name
mama.entitlement.appid = <num> application id known to permission system
mama.entitlement.effective_ip_address= <ip address> adress to use in position id
mama.entitlement.entitlement_system = <FILE|DACS> entitlement system used in position id
mama.entitlement.siteid = <string> site id or domain used in position id
mama.entitlement.transport.<name>.source = <string> source name for transport used by basic subscriber (TOPIC only subscription)
mama.entitlement.log.level = <0-6> 0-None,1-Error,2-API calls,3-XML,4-Debug,5-Pump,6-Mutex
mama.entitlement.log.filename = <filename or stdout/stderr>
mama.entitlement.log.size = <num K> max log file size in K before rolling
mama.entitlement.log.max_backup = <num> max number of rolled log files to retain>
mama.entitlement.cache_filename = <filename> file to store local PE cache
mama.entitlement.user_timeout = <seconds> timeout for login and getall
mama.entitlement.connect_timeout = <seconds> timeout for server connection
mama.entitlement.getpe_all = <true/false> enable ALL switch for getall
mama.entitlement.getpe_timeout = <seconds> timeout for getpe
mama.entitlement.auto_getall = <true/false> enable automatic getall
mama.entitlement.enable_ping = <true/false> enable ping
mama.entitlement.enable_events = <true/false> enable automatic event updates
mama.entitlement.enable_getpe = <true/false> enable getpe
mama.entitlement.failover_notify = <true/false> enable server failover notify

Signed-off-by: David Sewell david.sewell@citihub.com
---
diff --git a/mama/c_cpp/configure.ac b/mama/c_cpp/configure.ac
index 1bae611..daadc23 100644
--- a/mama/c_cpp/configure.ac
+++ b/mama/c_cpp/configure.ac
@@ -178,6 +178,44 @@ then
fi

##################################################
+# CHUB_PERMSVR: --with-chub-permsvr
+# Whether or not to link in libPermSvr
+##################################################
+AC_ARG_WITH(
+ chub_permsvr,
+ [AC_HELP_STRING([--with-chub-permsvr=DIR],
+ [Location of libPermSvr SRC in DIR])],
+ [
+ if test -d "$withval"; then
+ CHUB_HOME="$withval"
+ fi
+ ]
+ AC_CHECK_FILE(
+ [$CHUB_HOME/include/libPermSvr.h],
+ [
+ CPPFLAGS="$CPPFLAGS -DWITH_CHUB_PERMSVR -I$CHUB_HOME/include"
+ LDFLAGS="$LDFLAGS -L$WOMBATMSG_HOME/lib -L$CHUB_HOME/lib"
+ LIBS="$LIBS -lPermSvr"
+ with_chub_permsvr=true
+ ],
+ [
+ AC_MSG_FAILURE([Building with libPermSvr Failed.])
+ ])
+ )
+AC_SUBST(chub_permsvr_dir,[$CHUB_HOME])
+AM_CONDITIONAL(WITH_CHUB_PERMSVR, test x$with_chub_permsvr = "xtrue")
+
+if test x$with_chub_permsvr = xtrue
+then
+ AC_MSG_CHECKING(for Solaris)
+ case "$host" in
+ *-solaris*)
+ LIBS="$LIBS -lnsl -lsocket"
+ ;;
+ esac
+fi
+
+##################################################
# AVIS: --with-avis
# Whether or not to link in the Avis middleware
##################################################
diff --git a/mama/c_cpp/src/c/listenermsgcallback.c b/mama/c_cpp/src/c/listenermsgcallback.c
index 4ff9ea4..108031e 100644
--- a/mama/c_cpp/src/c/listenermsgcallback.c
+++ b/mama/c_cpp/src/c/listenermsgcallback.c
@@ -38,6 +38,9 @@
#ifdef WITH_ENTITLEMENTS
#include <OeaClient.h>
extern oeaClient * gEntitlementClient;
+#elif WITH_CHUB_PERMSVR
+#include <libPermSvr.h>
+extern int gEntitlementClient;
#endif /* WITH_ENTITLEMENTS */


@@ -84,6 +87,11 @@ listenerMsgCallback_create( listenerMsgCallback *result,
{
return MAMA_ENTITLE_NO_SERVERS_SPECIFIED;
}
+#elif WITH_CHUB_PERMSVR
+ if( gEntitlementClient == 0 )
+ {
+ return MAMA_ENTITLE_NO_SERVERS_SPECIFIED;
+ }
#endif /* WITH_ENTITLEMENTS */

if( callback == NULL )
@@ -549,6 +557,90 @@ checkEntitlement( msgCallback *callback, mamaMsg msg, SubjectContext* ctx )
}

return result;
+#elif WITH_CHUB_PERMSVR
+ int result = 0;
+ int32_t value;
+ int32_t count;
+ if( ctx->mEntitlementAlreadyVerified )
+ {
+ return 1;
+ }
+
+ if( MAMA_STATUS_OK == mamaMsg_getEntitleCode( msg,
+ &value ) )
+ {
+ if ((gMamaLogLevel >= MAMA_LOG_LEVEL_FINER) ||
+ (mamaSubscription_checkDebugLevel (self->mSubscription,
+ MAMA_LOG_LEVEL_FINER)))
+ {
+ mama_log (MAMA_LOG_LEVEL_FINER,
+ "Checking injected entitlement: %d\n", value);
+ }
+
+ if( value == 0 )
+ {
+ return 1;
+ }
+ const char* userSymbol = NULL;
+ const char* userSource = NULL;
+ void* closure = NULL;
+
+ mamaSubscription_getSymbol (self->mSubscription, &userSymbol);
+ mamaSubscription_getSource (self->mSubscription, &userSource);
+ mamaSubscription_getClosure (self->mSubscription, &closure);
+ ctx->mEntitleCode = value;
+ result = CHUB_IsPermissionedPE( gEntitlementClient,
+ (char *)0,
+ userSource,
+ userSymbol,
+ &ctx->mEntitleCode,
+ &count);
+ printf ("svc=%s, ric=%s, pe=%d %s\n", userSource,
+ userSymbol,
+ ctx->mEntitleCode,
+ CHUB_GetPermCodeStr(result));
+ if ((gMamaLogLevel >= MAMA_LOG_LEVEL_FINER) ||
+ (mamaSubscription_checkDebugLevel (self->mSubscription,
+ MAMA_LOG_LEVEL_FINER)))
+ {
+ mama_log (MAMA_LOG_LEVEL_FINER,
+ "Entitlement: source=%s, symbol=%s, code=%d, count=%d, permission=%s\n",
+ userSource,
+ userSymbol,
+ ctx->mEntitleCode,
+ CHUB_GetPermCodeStr(result)
+ );
+ }
+ if (!result)
+ {
+
+ mamaMsgCallbacks *cbs =
+ mamaSubscription_getUserCallbacks (self->mSubscription);
+
+ mama_setLastError (MAMA_ERROR_NOT_ENTITLED);
+
+ mamaSubscription_deactivate (self->mSubscription);
+
+ cbs->onError (self->mSubscription,
+ MAMA_STATUS_NOT_ENTITLED,
+ NULL,
+ userSymbol,
+ closure);
+ }
+ }
+ else
+ {
+ /* This is only temporary until the entitle code is sent with
+ * every message. */
+ return 1;
+ }
+
+ if( result )
+ {
+ ctx->mEntitlementAlreadyVerified = 1;
+ }
+
+ return result;
#else
return 1;
#endif /* WITH_ENTITLEMENTS */
diff --git a/mama/c_cpp/src/c/mama.c b/mama/c_cpp/src/c/mama.c
index ee0d6a0..59c2233 100644
--- a/mama/c_cpp/src/c/mama.c
+++ b/mama/c_cpp/src/c/mama.c
@@ -104,6 +104,16 @@ static const char* gServerProperty = NULL;
static const char* gServers[MAX_ENTITLEMENT_SERVERS];
static mama_status enableEntitlements (const char **servers);
static const char* gEntitled = "entitled";
+#elif WITH_CHUB_PERMSVR
+#include <libPermSvr.h>
+#define SERVERS_PROPERTY "entitlement.servers"
+#define MAX_ENTITLEMENT_SERVERS 32
+#define MAX_USER_NAME_STR_LEN 64
+#define MAX_HOST_NAME_STR_LEN 64
+CHUBLibAttr *gCHUBLibAttr = (CHUBLibAttr *)0;
+int gEntitlementClient = 0;
+static mama_status enableEntitlements (const char *servers);
+static const char* gEntitled = "entitled libPermSvr";
#else
static const char* gEntitled = "not entitled";
#endif /*WITH_ENTITLEMENTS */
@@ -858,13 +868,7 @@ mama_openWithProperties (const char* path,
return MAMA_STATUS_NO_BRIDGE_IMPL;
}

-#ifndef WITH_ENTITLEMENTS
- mama_log (MAMA_LOG_LEVEL_WARN,
- "\n********************************************************************************\n"
- "Note: This build of the MAMA API is not enforcing entitlement checks.\n"
- "Please see the Licensing file for details\n"
- "**********************************************************************************");
-#else
+#ifdef WITH_ENTITLEMENTS
result = enableEntitlements (NULL);
if (result != MAMA_STATUS_OK)
{
@@ -874,6 +878,22 @@ mama_openWithProperties (const char* path,
mama_close();
return result;
}
+#elif WITH_CHUB_PERMSVR
+ result = enableEntitlements (NULL);
+ if (result != MAMA_STATUS_OK)
+ {
+ mama_log (MAMA_LOG_LEVEL_SEVERE,
+ "mama_openWithProperties(): "
+ "Error connecting to Entitlements Server");
+ mama_close();
+ return result;
+ }
+#else
+ mama_log (MAMA_LOG_LEVEL_WARN,
+ "\n********************************************************************************\n"
+ "Note: This build of the MAMA API is not enforcing entitlement checks.\n"
+ "Please see the Licensing file for details\n"
+ "**********************************************************************************");
#endif /* WITH_ENTITLEMENTS */

if (strtobool(statsLogging))
@@ -1058,6 +1078,12 @@ mama_close ()
oeaClient_destroy( gEntitlementClient );
gEntitlementClient = 0;
}
+#elif WITH_CHUB_PERMSVR
+ if( gEntitlementClient != 0 )
+ {
+ CHUB_Destroy( gEntitlementClient );
+ gEntitlementClient = 0;
+ }
#endif /* WITH_ENTITLEMENTS */

pthread_key_delete(last_err_key);
@@ -1668,6 +1694,201 @@ enableEntitlements (const char **servers)

return MAMA_STATUS_OK;
}
+#elif WITH_CHUB_PERMSVR
+static mama_status
+enableEntitlements (const char *servers)
+{
+ char buf[K];
+ int32_t iDbg = 0;
+ int32_t iSize = K;
+ int32_t iMaxBkup = 3;
+ const char* pDbg = NULL;
+ const char* userID = (const char *)0;
+ char* posID = buf;
+ const char* ipAddr = (const char *)0;
+ const char* appID = (const char *)0;
+ const char* pServers = servers;
+ const char* pPropertyValue = (const char *)0;
+
+
+ if (gEntitlementClient != 0)
+ {
+ CHUB_Destroy(gEntitlementClient);
+ gEntitlementClient = 0;
+ }
+
+ mama_getUserName (&userID);
+ lookupIPAddress();
+
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.servers");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ pServers = strdup ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.altposid");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ posID += sprintf( posID, "%s", pPropertyValue );
+ }
+ else
+ {
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.altuserid");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ userID = strdup ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.appid" );
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ appID = strdup ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.effective_ip_address");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ ipAddr = strdup ( pPropertyValue );
+ }
+ else
+ {
+ ipAddr = gIPAddress;
+ }
+ if ( userID )
+ {
+ posID += sprintf( posID, "%s", userID );
+ if ( appID )
+ {
+ posID += sprintf( posID, "+%s", appID );
+ if ( ipAddr )
+ {
+ posID += sprintf( posID, "+%s/net", ipAddr );
+ }
+ else
+ {
+ posID += sprintf( posID, "+127.0.0.1/net" );
+ }
+ }
+ }
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.entitlement_system");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ posID += sprintf ( posID, ":%s", pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.siteid");
+ if ( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ posID += sprintf ( posID, "+%s", pPropertyValue );
+ }
+ posID = strdup ( buf );
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.log.level" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ iDbg = atoi ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.log.filename" );
+ if( pPropertyValue )
+ {
+ pDbg = strdup ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.log.size" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 ) {
+ iSize = atoi ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.log.max_backup" );
+ if( pPropertyValue && isdigit( pPropertyValue ) )
+ {
+ iMaxBkup = atoi ( pPropertyValue );
+ }
+
+ mama_log (MAMA_LOG_LEVEL_NORMAL,
+ "%s", CHUB_Version());
+
+ if ( iDbg ) {
+ CHUB_RollingLog( (const char*)pDbg, iDbg, iSize*K, iMaxBkup );
+ sprintf( buf, "%s\n", CHUB_Version());
+ CHUB_Logger( 0, buf );
+ sprintf( buf, "Logging enabled: %s [level %d]\n", pDbg, iDbg );
+ CHUB_Logger( 0, buf );
+ }
+
+ gCHUBLibAttr = (CHUBLibAttr *)calloc( 1, sizeof( CHUBLibAttr ) );
+ CHUB_GetLibAttr( 0, gCHUBLibAttr );
+
+ if ( !gCHUBLibAttr )
+ {
+ return MAMA_STATUS_SYSTEM_ERROR;
+ }
+
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.cache_filename" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_pCBEFile = strdup ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.user_timeout" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_nUserTout = strtod ( pPropertyValue, NULL );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.connect_timeout" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_nConnectTout = atoi ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.getpe_all" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bGetPEAll = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.getpe_timeout" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_nGetPETout = atoi ( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.auto_getall" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bAutoGetAll = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.enable_ping" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bChannelPing = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.enable_events" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bChannelEvent = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.enable_getpe" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bChannelGetPE = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+ pPropertyValue = properties_Get (gProperties, "mama.entitlement.failover_notify" );
+ if( pPropertyValue && strlen(pPropertyValue)>0 )
+ {
+ gCHUBLibAttr->_bSFN = properties_GetPropertyValueAsBoolean( pPropertyValue );
+ }
+
+ mama_log (MAMA_LOG_LEVEL_NORMAL,
+ "Entitlement position ID : %s", posID );
+ mama_log (MAMA_LOG_LEVEL_NORMAL,
+ "Attempting to connect to entitlement server : %s",
+ pServers );
+
+ if ( !pServers || !strlen( pServers ) )
+ {
+ return MAMA_ENTITLE_NO_SERVERS_SPECIFIED;
+ }
+
+ gEntitlementClient = CHUB_InitializeSingleUser( pServers, posID, gCHUBLibAttr );
+
+ if (!gEntitlementClient)
+ {
+ return MAMA_ENTITLE_SERVER_NOT_FOUND;
+ }
+
+ return MAMA_STATUS_OK;
+}

#endif

diff --git a/mama/c_cpp/src/c/mama/mama.h b/mama/c_cpp/src/c/mama/mama.h
index 658bce6..65bfd49 100644
--- a/mama/c_cpp/src/c/mama/mama.h
+++ b/mama/c_cpp/src/c/mama/mama.h
@@ -67,6 +67,8 @@ extern "C"
#define MAMA_MAX_SYMBOL_LEN 128
#define MAMA_MAX_SOURCE_LEN 64
#define MAMA_MAX_TRANSPORT_LEN 64
+#define K 1024
+

/**
* \mainpage Middleware Agnostic Messaging API (MAMA) C API
diff --git a/mama/c_cpp/src/c/mama/status.h b/mama/c_cpp/src/c/mama/status.h
index bccb7e0..2ad75b7 100644
--- a/mama/c_cpp/src/c/mama/status.h
+++ b/mama/c_cpp/src/c/mama/status.h
@@ -27,6 +27,8 @@

#ifdef WITH_ENTITLEMENTS
#include <OeaStatus.h>
+#elif WITH_CHUB_PERMSVR
+#include <libPermSvr.h>
#endif


@@ -163,6 +165,9 @@ typedef enum
MAMA_ENTITLE_NO_USER = MAMA_ENTITLE_HTTP_OVERLOAD + 1, /* 9029 */
MAMA_ENTITLE_NO_SERVERS_SPECIFIED = MAMA_ENTITLE_NO_USER + 1, /* 9030 */
MAMA_ENTITLE_SITE_NOT_FOUND = MAMA_STATUS_BASE + OEA_STATUS_SITE_NOT_FOUND /* 9032 */
+#elif WITH_CHUB_PERMSVR
+ ,MAMA_ENTITLE_NO_SERVERS_SPECIFIED = MAMA_STATUS_BASE + 1, /* 9006 */
+ MAMA_ENTITLE_SERVER_NOT_FOUND = MAMA_ENTITLE_NO_SERVERS_SPECIFIED + 1 /* 9008 */
#endif
} mama_status;

diff --git a/mama/c_cpp/src/c/publisher.c b/mama/c_cpp/src/c/publisher.c
index 500465e..91683b2 100644
--- a/mama/c_cpp/src/c/publisher.c
+++ b/mama/c_cpp/src/c/publisher.c
@@ -21,6 +21,7 @@

#include "mama/mama.h"
#include "mama/publisher.h"
+#include "mama/types.h"

#include "bridge.h"
#include "throttle.h"
@@ -31,6 +32,13 @@

#include "list.h"

+#ifdef WITH_CHUB_PERMSVR
+
+#include <libPermSvr.h>
+extern int gEntitlementClient;
+
+#endif /* WITH_CHUB_PERMSVR */
+
/*Main mamaPublisher structure for the API*/
typedef struct mamaPublisherImpl_
{
@@ -57,6 +65,38 @@ struct publisherClosure
void* mSendCompleteClosure;
};

+/* *************************************************** */
+/* Internal Functions. */
+/* *************************************************** */
+#ifdef WITH_CHUB_PERMSVR
+static int
+isEntitledToPublish (const char *source, const char*symbol)
+{
+ int result = 0;
+ int count = 0;
+#define MAX_PUBLISH_SOURCE_SIZE 261 /* 256 + 5 */
+ char tsource[MAX_PUBLISH_SOURCE_SIZE];
+ if ( NULL!=source)
+ {
+ snprintf( tsource, MAX_PUBLISH_SOURCE_SIZE, "_pub.%s", source );
+ }
+
+ if (gEntitlementClient == 0) /* Not enforcing entitlements. */
+ {
+ return 1;
+ }
+
+ result = CHUB_IsPermissionedPE( gEntitlementClient,
+ (char *)0,
+ tsource,
+ symbol,
+ 0,
+ 0 );
+
+ return result;
+}
+#endif /* WITH_ENTITLEMENTS */
+
static mama_status
_createByIndex (mamaPublisher* result,
mamaTransport tport,
@@ -91,6 +131,23 @@ _createByIndex (mamaPublisher* result,
source ? source : "",
symbol ? symbol : "");

+#ifdef WITH_CHUB_PERMSVR
+ const char *tsource;
+ if ( NULL!=source)
+ {
+ tsource = source;
+ }
+ else
+ {
+ mamaTransport_getDefSource(tport, &tsource);
+ }
+ /*Up from entitlement check based on string compare on symbol*/
+ if (!isEntitledToPublish (tsource, symbol))
+ {
+ return MAMA_STATUS_NOT_ENTITLED;
+ }
+#endif
+
/*Get the bridge impl from the transport - mandatory*/
bridgeImpl = mamaTransportImpl_getBridgeImpl (tport);
if (!bridgeImpl) return MAMA_STATUS_NO_BRIDGE_IMPL;
diff --git a/mama/c_cpp/src/c/status.c b/mama/c_cpp/src/c/status.c
index 1c394e3..b3aea59 100644
--- a/mama/c_cpp/src/c/status.c
+++ b/mama/c_cpp/src/c/status.c
@@ -113,6 +113,9 @@ mamaStatus_stringForStatus (mama_status status)
case MAMA_ENTITLE_NO_USER : return "ENTITLE_NO_USER";
case MAMA_ENTITLE_NO_SERVERS_SPECIFIED : return "ENTITLE_NO_SERVERS_SPECIFIED";
case MAMA_ENTITLE_SITE_NOT_FOUND : return "ENTITLE_SITE_NOT_FOUND";
+#elif WITH_CHUB_PERMSVR
+ case MAMA_ENTITLE_NO_SERVERS_SPECIFIED : return "MAMA_ENTITLE_NO_SERVERS_SPECIFIED";
+ case MAMA_ENTITLE_SERVER_NOT_FOUND : return "MAMA_ENTITLE_SERVER_NOT_FOUND";
#endif
}
return "unknown";
diff --git a/mama/c_cpp/src/c/subscription.c b/mama/c_cpp/src/c/subscription.c
index d6d0c00..8eaa248 100644
--- a/mama/c_cpp/src/c/subscription.c
+++ b/mama/c_cpp/src/c/subscription.c
@@ -52,6 +52,11 @@
#include <OeaSubscription.h>
extern oeaClient * gEntitlementClient;

+#elif WITH_CHUB_PERMSVR
+
+#include <libPermSvr.h>
+extern int gEntitlementClient;
+
#endif /* WITH_ENTITLEMENTS */

/* *************************************************** */
@@ -525,6 +530,24 @@ isEntitledToSymbol (const char *source, const char*symbol, mamaSubscription subs
result = oeaSubscription_isAllowed (impl->mSubjectContext.mOeaSubscription);

return result;
+#elif WITH_CHUB_PERMSVR
+ int result = 0;
+ int count = 0;
+ mamaSubscriptionImpl *impl = (mamaSubscriptionImpl *)subscription;
+
+ if (gEntitlementClient == 0) /* Not enforcing entitlements. */
+ {
+ return 1;
+ }
+
+ result = CHUB_IsPermissionedPE( gEntitlementClient,
+ (char *)0,
+ source,
+ symbol,
+ &impl->mSubjectContext.mEntitleCode,
+ &count );
+
+ return result;
#else
return 1;
#endif /* WITH_ENTITLEMENTS */
@@ -951,6 +974,8 @@ mama_status mamaSubscription_processMsg(mamaSubscription subscription, mamaMsg m

#ifdef WITH_ENTITLEMENTS
mamaMsg_getEntitleCode (message, &entitleCode);
+#elif WITH_CHUB_PERMSVR
+ mamaMsg_getEntitleCode (message, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -993,6 +1018,8 @@ mama_status mamaSubscription_processTportMsg(mamaSubscription subscription, mama

#ifdef WITH_ENTITLEMENTS
mamaMsg_getEntitleCode (msg, &entitleCode);
+#elif WITH_CHUB_PERMSVR
+ mamaMsg_getEntitleCode (msg, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -1038,6 +1065,8 @@ mama_status mamaSubscription_processWildCardMsg(mamaSubscription subscription, m

#ifdef WITH_ENTITLEMENTS
mamaMsg_getEntitleCode (msg, &entitleCode);
+#elif WITH_CHUB_PERMSVR
+ mamaMsg_getEntitleCode (msg, &entitleCode);
#endif
if (entitleCode == 0)
{
@@ -2656,6 +2685,17 @@ mama_status mamaSubscription_createBasic(mamaSubscription subscription, mamaTran

else
{
+#ifdef WITH_CHUB_PERMSVR
+ /* Get entitlements source from transport */
+ const char *tsource;
+ mamaTransport_getDefSource(transport, &tsource);
+ /*Up from entitlement check based on string compare on symbol*/
+ if (!isEntitledToSymbol (tsource, topic, impl))
+ {
+ setSubscInfo (impl, transport, NULL, tsource, topic);
+ return MAMA_STATUS_NOT_ENTITLED;
+ }
+#endif
/* Initialise the impl. */
impl->mClosure = closure;
impl->mQueue = queue;
diff --git a/mama/c_cpp/src/c/subscriptionimpl.h b/mama/c_cpp/src/c/subscriptionimpl.h
index eaad852..63cd6b7 100644
--- a/mama/c_cpp/src/c/subscriptionimpl.h
+++ b/mama/c_cpp/src/c/subscriptionimpl.h
@@ -93,6 +93,10 @@ typedef struct SubjectContext_
int32_t mEntitleCode;
uint8_t mEntitlementAlreadyVerified;
oeaSubscription* mOeaSubscription;
+#elif WITH_CHUB_PERMSVR
+ EntitleStatus mEntitlement; /* default to NOT_DETERMINED! */
+ int32_t mEntitleCode;
+ uint8_t mEntitlementAlreadyVerified;
#endif
/* The data quality context includes a recap request. */
mamaDqContext mDqContext;
diff --git a/mama/c_cpp/src/c/transport.c b/mama/c_cpp/src/c/transport.c
index de92a56..fe18ee2 100644
--- a/mama/c_cpp/src/c/transport.c
+++ b/mama/c_cpp/src/c/transport.c
@@ -116,6 +116,9 @@ typedef struct transportImpl_

refreshTransport mRefreshTransport;
char mName[MAX_TPORT_NAME_LEN];
+#ifdef WITH_CHUB_PERMSVR
+ char mDefSource[MAX_TPORT_NAME_LEN];
+#endif
mamaCmResponder mCmResponder;
char* mDescription;

@@ -526,6 +529,28 @@ mamaTransport_create (mamaTransport transport,

mama_log (MAMA_LOG_LEVEL_FINE, "Creating transport: [%s]",
name ? name : "");
+#ifdef WITH_CHUB_PERMSVR
+ const char* propValue = NULL;
+ char propNameBuf[MAX_TPORT_NAME_LEN];
+
+ snprintf (propNameBuf, MAX_TPORT_NAME_LEN, "mama.entitlement.transport.%s.source", self->mName);
+
+ propValue = properties_Get (mamaInternal_getProperties (),
+ propNameBuf);
+
+ if (NULL!=propValue)
+ {
+ mama_log (MAMA_LOG_LEVEL_NORMAL, "Setting %s=%s",
+ propNameBuf, propValue);
+ snprintf (self->mDefSource, MAX_TPORT_NAME_LEN, "%s", propValue);
+ self->mDefSource[MAX_TPORT_NAME_LEN-1] = '\0';
+ }
+ else
+ {
+ snprintf (self->mDefSource, MAX_TPORT_NAME_LEN, "%s", self->mName);
+ self->mDefSource[MAX_TPORT_NAME_LEN-1] = '\0';
+ }
+#endif

if (MAMA_STATUS_OK!=(status=mama_getDefaultEventQueue (
(mamaBridge)(self->mBridgeImpl), &defaultQueue)))
@@ -1236,6 +1261,28 @@ mamaTransport_setName (mamaTransport transport,
{
mamaStatsCollector_setName (*self->mStatsCollector, self->mName);
}
+#ifdef WITH_CHUB_PERMSVR
+ const char* propValue = NULL;
+ char propNameBuf[MAX_TPORT_NAME_LEN];
+
+ snprintf (propNameBuf, MAX_TPORT_NAME_LEN, "mama.entitlement.transport.%s.source", self->mName);
+
+ propValue = properties_Get (mamaInternal_getProperties (),
+ propNameBuf);
+
+ if (NULL!=propValue)
+ {
+ mama_log (MAMA_LOG_LEVEL_NORMAL, "Setting %s=%s",
+ propNameBuf, propValue);
+ snprintf (self->mDefSource, MAX_TPORT_NAME_LEN, "%s", propValue);
+ self->mDefSource[MAX_TPORT_NAME_LEN-1] = '\0';
+ }
+ else
+ {
+ snprintf (self->mDefSource, MAX_TPORT_NAME_LEN, "%s", self->mName);
+ self->mDefSource[MAX_TPORT_NAME_LEN-1] = '\0';
+ }
+#endif

return MAMA_STATUS_OK;
}
@@ -1253,6 +1300,21 @@ mamaTransport_getName (mamaTransport transport,
return MAMA_STATUS_OK;
}

+#ifdef WITH_CHUB_PERMSVR
+mama_status
+mamaTransport_getDefSource (mamaTransport transport,
+ const char** result)
+{
+ if (!self)
+ {
+ *result = NULL;
+ return MAMA_STATUS_NULL_ARG;
+ }
+ *result = self->mDefSource;
+ return MAMA_STATUS_OK;
+}
+#endif
+
const char *
mamaTransport_getMiddleware (mamaTransport transport)
{

This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Citihub. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error.