Created
May 9, 2013 10:40
-
-
Save ogarrett/5546803 to your computer and use it in GitHub Desktop.
iPlanet/SunONE/SunJavaSystem module to update internal record of connection source IP address to match value of X-Cluster-Client-IP header from Stingray Traffic Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*--------------------------------------------------------------------- | |
* | |
* Copyright (c) 2005 Zeus Technology | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in the | |
* documentation and/or other materials provided with the distribution. | |
* 3. Neither the name of Zeus Technology nor the names of its contributors | |
* may be used to endorse or promote products derived from this software | |
* without specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
* SUCH DAMAGE. | |
* | |
* iprewrite.c -- NSAPI module to understand the X-Cluster-Client-Ip | |
* header, and feed it into the sn->client->ip field | |
* | |
* Editing history | |
* 2005-12-02: Zeus Technology. Initial version ([email protected]) | |
* | |
NSAPI iprewrite SAF | |
=================== | |
This NSAPI SAF inspects the value of the X-Cluster-Client-IP header. | |
If the connection has come from a trusted IP address (such as a ZXTM | |
traffic manager), it replaces sn->client->ip with this value. | |
Initialise this module using 'iprewrite-init'. | |
You can call the 'iprewrite-all' SAF at the start of request | |
processing (i.e., AuthTrans). This will modify the Session | |
object, replacing the value of the 'ip' field in the client pblock | |
structure. Modifications will persist for the duration if the | |
session, but other modules may change this value later, or may notice | |
the discrepancy. | |
A less invasive alternative is to use the 'iprewrite-func' SAF to | |
modify the environment for a single nsapi SAF. The change only | |
persists for that single SAF. | |
Recommended usage: | |
#---------------------------------------------------------------------- | |
# magnus.conf: | |
Init fn="load-modules" \ | |
funcs="iprewrite-init,iprewrite-all,iprewrite-func" \ | |
shlib="/opt/iplanet6/plugins/libiprewrite.so" | |
Init fn="iprewrite-init" TrustedIPs="10.100.1.1 10.100.1.2" | |
# obj.conf: Using iprewrite-all | |
<Object name="default"> | |
AuthTrans fn="iprewrite-all" | |
</Object> | |
# obj.conf: Using iprewrite-func | |
<Object name="weblogic" ppath="star/weblogic/star"> | |
Service fn=iprewrite-func func=wl_proxy \ | |
WebLogicHost=localhost WebLogicPort=7001 PathTrim="/weblogic" | |
</Object> | |
In star/weblogic/star, replace 'star' with '*' (C-commenting problem!) | |
#---------------------------------------------------------------------- | |
Compilation: | |
cc -Kpic -I/opt/iplanet6/plugins/include \ | |
-DNET_SSL -DSOLARIS -D_REENTRANT -DMCC_HTTPD -DXP_UNIX -DSPAPI20 \ | |
-c iprewrite.c | |
ld -G -o libiprewrite.so iprewrite.o | |
For other platforms, copy the compilation options used when making the | |
samples in /opt/iplanet6/plugins/nsapi/examples/ | |
---------------------------------------------------------------------*/ | |
#include <string.h> | |
#include <stdlib.h> | |
#include <nsapi.h> | |
/* must be in lower (Netscape) case */ | |
static char* zxtmheader = (char*)"x-cluster-client-ip"; | |
/* Module-global configuration */ | |
static pblock *trusted_ips = 0; | |
static int trust_all_ips = 0; | |
/* Given a client session, check that it is authorized against the | |
* TrustedIPs value. Note that different client sessions (with | |
* different X-Cluster-Client-IP headers) may be multiplexed down | |
* the same HTTP connection */ | |
static int authorized( Session *sn ) | |
{ | |
const char *trusted = 0; | |
if( trust_all_ips ) { | |
return 1; | |
} | |
trusted = pblock_findval( "zxtm-trusted", sn->client ); | |
if( trusted ) return ( trusted[0] == 'Y' ); | |
if( trusted_ips ) { | |
const char* remote_ip = pblock_findval( "ip", sn->client ); | |
if( remote_ip && pblock_findval( remote_ip, trusted_ips ) ) { | |
pblock_nvinsert( "zxtm-trusted", "Y", sn->client ); | |
return 1; | |
} | |
} | |
pblock_nvinsert( "zxtm-trusted", "N", sn->client ); | |
return 0; | |
} | |
/* Read the TrustedIPs configuration and build the internal | |
configuration */ | |
int iprewrite_init( pblock *args, Session *sn, Request *rq ) | |
{ | |
const char *iplist = pblock_findval( "TrustedIPs", args ); | |
if( !iplist ) { | |
log_error( LOG_MISCONFIG, (char*)"iprewrite_init", sn, rq, | |
(char*)"No TrustedIPs configured. Disabling this module." ); | |
return REQ_ABORTED; | |
} | |
if( strcmp( iplist, "*" ) == 0 ) { | |
log_ereport( LOG_INFORM, | |
(char*)"iprewrite_init: Trusting all remote clients." ); | |
trust_all_ips = 1; | |
} else { | |
char *l = strdup( iplist ); | |
char *ptrptr = 0; | |
char *ip = strtok_r( l, (char*)" ", &ptrptr ); | |
trusted_ips = pblock_create( 4 ); | |
while( ip ) { | |
pblock_nvinsert( ip, "", trusted_ips ); | |
log_ereport( LOG_INFORM, (char*)"iprewrite-init: Trusting %s", ip ); | |
ip = strtok_r( 0, (char*)" ", &ptrptr ); | |
} | |
free( l ); | |
} | |
return REQ_PROCEED; | |
} | |
/* Modify the sn->client->ip value for the rest of the client session */ | |
int iprewrite_all( pblock *args, Session *sn, Request *rq ) | |
{ | |
char* x_cluster_client_ip; | |
x_cluster_client_ip = 0; | |
request_header( zxtmheader, &x_cluster_client_ip, sn, rq ); | |
if( !x_cluster_client_ip ) return REQ_NOACTION; /* header missing */ | |
if( ! authorized( sn ) ) { | |
log_ereport( LOG_WARN, (char*)"Ignoring X-Cluster-Client-Ip '%s' from non-Load Balancer machine '%s'", | |
x_cluster_client_ip, pblock_findval( "ip", sn->client ) ); | |
return REQ_NOACTION; | |
} | |
pblock_nvinsert( "ip", x_cluster_client_ip, sn->client ); | |
pblock_nvinsert( "dns", x_cluster_client_ip, sn->client ); | |
return REQ_NOACTION; | |
} | |
/* Modify the sn->client->ip value for the named function call only */ | |
int iprewrite_func( pblock *args, Session *sn, Request *rq ) | |
{ | |
char* x_cluster_client_ip; | |
char* func; | |
pblock* newargs; | |
int ret; | |
int auth = 0; | |
func = pblock_findval( "func", args ); | |
if( !func ) { | |
log_ereport( LOG_INFORM, (char*)"iprewrite-func: no func provided" ); | |
return REQ_ABORTED; | |
} | |
newargs = pblock_dup( args ); | |
pblock_nvinsert( "fn", func, newargs ); | |
param_free( pblock_remove( "func", newargs )); | |
x_cluster_client_ip = 0; | |
request_header( zxtmheader, &x_cluster_client_ip, sn, rq ); | |
if( x_cluster_client_ip ) { | |
if( ! authorized( sn ) ) { | |
log_ereport( LOG_WARN, (char*)"Ignoring X-Cluster-Client-Ip '%s' from non-Load Balancer machine '%s'", | |
x_cluster_client_ip, pblock_findval( "ip", sn->client ) ); | |
ret = func_exec( newargs, sn, rq ); | |
} else { | |
char *real_ip = pblock_findval("ip", sn->client); | |
char *real_dns = pblock_findval("dns", sn->client); | |
pblock_nvinsert( "ip", x_cluster_client_ip, sn->client ); | |
if( real_dns ) pblock_nvinsert( "dns", x_cluster_client_ip, sn->client ); | |
ret = func_exec( newargs, sn, rq ); | |
pblock_nvinsert( "ip", real_ip, sn->client ); | |
if( real_dns ) pblock_nvinsert( "dns", real_dns, sn->client ); | |
} | |
} else { | |
/* no x_cluster_client_ip */ | |
ret = func_exec( newargs, sn, rq ); | |
} | |
pblock_free( newargs ); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment