Previous Topic: API OverviewNext Topic: Central Host Configuration


Guidance for the Agent API in C

This section contains the following topics:

Agent API Overview

About the SiteMinder Agent

Agent Initialization

Agent Discovery

How to Access a Resource Using the Agent API

Compile and Link a Custom Agent

Central Host Configuration

Agent Call Sequence

Sample Custom Agent

Agent API Services

Response Attributes

Custom Agents and Single Sign-On

Memory Deallocation

Agent API Data Structures (C)

Agent API Function Declarations (C)

Agent API Overview

The Agent API works with the Policy Server to simplify application development and make applications more scalable. Developers creating applications that are built using the Agent API either directly or indirectly (through another agent) are shielded from the following implementation-specific details:

Additional benefits provided by the Agent API include full session management support, automatic encryption key rollover, and real-time policy updates.

About the SiteMinder Agent

A SiteMinder Agent is a client of the Agent API. The agent enforces access control policies provided by the Policy Server. The Policy Server is a general-purpose policy engine with no information about resources. Agents establish resource semantics and act as gate keepers to protect resources from unauthorized users.

Different agent types protect different kinds of resources. Some agent types are pre-defined, standard agents that are shipped as part of the SiteMinder product—for example, the Web Agent, which provides HTTP access control for Web Servers. You can also use the Agent API to implement custom agents.

When you create an application using the Agent API, you can create a custom agent to authenticate and authorize users in a variety of ways, depending on the context. For example, you could create an agent for FTP transfers that implements the following functionality:

When you build a custom agent with the SDK, you must run the custom agent against the version of the SiteMinder Policy Server that corresponds to the version of the SDK.

Agent Initialization

Before an agent can perform work on behalf of its users, it must initialize connections to one or more Policy Servers by calling Sm_AgentApi_Init(). Calling Sm_AgentApi_Init() lets you specify connection parameters such as failover mode and connection pool size. This call creates TCP connections and typically does not need to be done more than once per agent instance.

It is possible to initialize more than one API instance (for example, when working with Policy Servers that use separate policy stores).

Immediately after initialization, the agent should communicate its version information to the Policy Server by calling Sm_AgentApi_DoManagement() with the command SM_AGENTAPI_MANAGEMENT_SET_AGENT_INFO set in the structure Sm_AgentApi_ManagementContext_t. The actual information can be any string containing enough information about the agent, such as the build number and version number. The string is recorded in the Policy Server logs.

Agent Discovery

Agent discovery lets CA SiteMinder® administrators track instances of different types of agents, including agents that have been deployed over a number of years. An agent instance can be any type of agent, for example, Web agent, custom agent, or ERP agent. To come under the purview of agent discovery, the agent must be active and in communication with the Policy Server.

Only 5.x agents and later can be tracked. For agents created before r12.5, the combination of the IP address and trusted host are used to identify the agent. Any change in this combination for the same agent results in multiple entries for the same agent.

A unique GUID identifies each r12.5 agent instance, which is stored in a configuration file. The Sm_AgentApi_SetAgentInstanceInfo() function plays a pivotal role in the process of agent discovery. The Sm_AgentApi_SetAgentInstanceInfo() function determines whether the configuration has a specified GUID for the agent instance. If a GUID is found, the agent has already been discovered and can be tracked. Otherwise, the function creates a GUID for the agent instance and writes it to the configuration file for subsequent invocations. Multiple agent instances cannot share a configuration file.

The Agent API provides the following for registering agent info:

	int SM_EXTERN Sm_AgentApi_SetAgentInstanceInfo (
	    const void* pHandle,
	    Sm_AgentApi_AgentDiscovery_t arrParams[], int nCount);

The following macros in SmAgentAPi.h define the supported named elements that can be passed in arrParams. These are all optional, and an agent provides as much, or as little, information as it relevant.

	#define SM_AGENT_INSTANCE_AGENTPRODUCTTYPE      "AGENTPRODUCTTYPE"

Example: WebAgent

	#define SM_AGENT_INSTANCE_AGENTPRODUCTVERSION   "AGENTPRODUCTVERSION"

Example: 1.0

	#define SM_AGENT_INSTANCE_AGENTPRODUCTSUBTYPE   "AGENTPRODUCTSUBTYPE"

Example: IIS

	#define SM_AGENT_INSTANCE_AGENTPRODUCTOSTYPE    "AGENTPRODUCTOSTYPE"

Example: Linux

	#define SM_AGENT_INSTANCE_AGENTIDFILE           "AGENTIDFILE"

Valid path to a text file with write permission, used to store a unique GUID. If a path to an empty file is passed, the agent API will generate a new GUID and write it to this file. In the future, this GUID can be read and used to uniquely identify the agent instance.

	#define SM_AGENT_INSTANCE_ACONAME               "ACONAME"

A value ACO name used by the agent.

#define SM_AGENT_INSTANCE_HCONAME               "HCONAME"

A valid HCO name used by the agent

	#define SM_AGENT_INSTANCE_FIPSMODE              "FIPSMODE"

The value store in SmHost.conf if host registration is used by the agent.

After Sm_AgentApi_SetAgentInstanceInfo is called successfully, the AgentAPI will make periodic calls to the Policy Server in the back ground like a heartbeat. Calling this API for the first time from an agent results in a new unique record created in the Agent Discovery table used by the policy server. If a GUID is available, this record is indexed by the GUID. It is best to provide an Agent ID file so that a valid GUID is used. Without this value, the agent instance cannot be tracked and maintained as a unique entity in the SiteMinder agent ecosystem.

The correct calling sequence is:

	Sm_AgentApi_Init
	Sm_AgentApi_SetAgentInstanceInfo
	..
	other calls to PS
	..
	Sm_AgentApi_Uninit 

Here is a source example that assumes Sm_AgentApi_Init has been called previously to establish pAgentApiHandle:

    Sm_AgentApi_AgentDiscovery_t arrParams[8] = {
				{SM_AGENT_INSTANCE_AGENTPRODUCTTYPE, "CustomAgent"},
    				{SM_AGENT_INSTANCE_AGENTPRODUCTVERSION, "1.0"},
    				{SM_AGENT_INSTANCE_AGENTPRODUCTSUBTYPE, "IIS"},
    				{SM_AGENT_INSTANCE_AGENTPRODUCTOSTYPE, "Windows"},
    				{SM_AGENT_INSTANCE_AGENTIDFILE, "c:\idfile.txt"},
    				{SM_AGENT_INSTANCE_ACONAME, "MyACO"},
    				{SM_AGENT_INSTANCE_HCONAME, "MyHCO"},
    				{SM_AGENT_INSTANCE_FIPSMODE, "COMPAT"}};
    int nCount = 8;
    
    // Call the Agent API to send the data
    int nResult = Sm_AgentApi_SetAgentInstanceInfo(pAgentApiHandle, arrParams, nCount);

    switch (nResult)
    {
        case SM_AGENTAPI_NOCONNECTION:
        case SM_AGENTAPI_FAILURE:
        case SM_AGENTAPI_TIMEOUT:
        {
	    // put error handling here
            break;
        }
        case SM_AGENTAPI_NO:
        {
	    // The call was refused - probably not properly formatted. This return indicates
	    // that the call ran on the PS and returned an explicit NO response, as opposed to
	    // some other connection or protocol error that might generate the conditions above.
            break;
        }
	case SM_AGENTAPI_YES:
	{
	    // Success
	    break;
	}
    } // switch (nResult)

(new related group 1)

Sm_AgentApi_AgentDiscovery_t

Sm_AgentApi_SetAgentInstanceInfo()

How to Access a Resource Using the Agent API

After the Agent API has been initialized, the agent can start accepting requests from its users, such as receiving GET requests for URLs.

The following steps describe what is required for an agent to grant access to a resource. The outcome of most steps can be cached to improve agent performance. The agent can choose to cache as little as possible or as much as possible.

To grant user access to a resource

  1. Accept a user request to access a resource. This is the application-specific request. For example, the Web Agent can accept a user’s GET request for a URL.
  2. Determine if the requested resource is protected by calling Sm_AgentApi_IsProtected(). If the resource is protected, the Policy Server returns the required credentials that must be obtained from the user to validate the user’s identity. If the resource is not protected, access to the requested resource should be allowed. The outcome of this step can be cached.

    Collect the required credentials from the user and authenticate the user by calling Sm_AgentApi_Login(). After successful authentication, the Policy Server creates a session and returns response attributes including the unique session ID and session specification. These response attributes are policy driven and may include user profile data, static or dynamic privileges, a number of pre-defined authentication state attributes, or any other data that was designated by a policy administrator.
    The agent can now perform session management by caching user session information and keeping track of session expiration.

  3. Validate that the user has access to the requested resource by calling Sm_AgentApi_Authorize(). After successful authorization, the Policy Server returns response attributes, including resource-specific privileges. These response attributes are policy driven and can include user profile data, static or dynamic privileges or any other data that was designated by a policy administrator. The user’s authorization information for the requested resource is available and can be cached to speed up future requests.
  4. (Optional) Log the transactions for authentication and authorization by calling Sm_AgentApi_Audit() if the agent performs authorizations out of its cache.
  5. Allow the user to access the resource when the user’s identity is known, authorization has been verified and the required entitlements obtained.
  6. (Optional) Issue a management request by calling Sm_AgentApi_DoManagement(). This is an optional step that is used to poll the Policy Server for update commands. In response to a command, agents can update encryption keys or flush caches.
  7. Release all API instances by calling Sm_AgentApi_UnInit() for each API instance. This closes TCP connections to all Policy Servers.

The Agent API does not provide a facility for caching in a manner that enforces session validity. By choosing to cache user sessions or resource-specific privileges, the agent becomes obligated to perform its own session management during each user request, because caching on the agent removes the need to contact the Policy Server to perform session validation or resource authorizations or both.

Compile and Link a Custom Agent

To enable your custom agent to interact with SiteMinder, compile your agent application with SmAgentAPI.h and link to the platform-specific library listed following. On UNIX platforms you must add the library to the environment variable that specifies the library search path. The variable takes a colon-separated list of directories and are also listed following.

Platform

Library

Directory

Variable Name

Windows

SmAgentAPI.lib

<install_path>\sdk\lib\win32\

 

Solaris

libsmagentapi.so

<install_path>/sdk/bin

LD_LIBRARY_PATH

HP-UX

libsmagentapi.so

<install_path>/sdk/bin

SHLIB_PATH

AIX

libsmagentapi.so

<install_path>/sdk/bin

LIBPATH

Linux

libsmagentapi.so

<install_path>/sdk/bin

LD_LIBRARY_PATH

Note: If you are building the agent API application using Microsoft Visual C++, make sure you link with ws2_32.lib.