Friday, March 17, 2023

Large File Cache

I've come to realize that the gateway does not always clean up after itself :O

Really it's probably Java's garbage collection, but either way if you see your partition filling up and can't find the files responsible this may help.

Out of the box the gateway will cache large message attachments to disk while it processes the request/response, if they exceed a certain size.  The attachment.diskThreshold cluster property is the limit if over which the attachment will be cached to disk.  You can increase this value to keep more attachments in memory and not have them written to disk, but keep in mind that means they are kept in RAM, so make sure you have enough if increasing this property.

A buildup of files on the opt partition should not effect gateway performance... except for those services that are using this attachments cache, though when there is no room on the opt partition the gateway will also stop writing log files, and really I don't trust that it wouldn't effect anything else given the importance of the opt partition.

You can map the attachments directory off of the opt partition to prevent blocking the logs (and whatever else might need space there), and you can also clear the files themselves.  These attachments are not required once the request/response have completed, but experience has shown me that they are not cleaned up in a timely fashion and this results in the full disk.  Even if you delete the file the disk space is not released by the running process because it is still holding the file as open which continues to reserve the space.  The process will eventually release them, but I've seen it take more than a week to do this (it probably waits until it's not busy, which may or may not happen for a while).  You can force it to release the files by restarting the process, but if your gateway is so busy that it can't release the files on its own then I'm guessing this would not be your preferred choice.  Here I detail another option; removing the files (which it usually does on its own even though it doesn't release them), and then truncate the reference (making the reserved space equal to 0).

The below commands will map the attachments folder over to the tmp partition without changing any setting or configuration of the gateway application itself so that if it does fill up then it won't effect running processes.

service ssg stop
cd /tmp
mkdir /tmp/attachments
chmod 775 attachments
chown gateway:layer7 attachments
cd /opt/SecureSpan/Gateway/node/default/var/
rm -f ./attachments/*
rmdir attachments/
ln -s /tmp/attachments attachments
chown -h gateway:layer7 attachments
service ssg start

The below script will delete the attachments older than 15 minutes and then detect which files are referenced by the gateway's java process and truncate the references to the deleted files.

(If you don't map over to /tmp/attachments then you'll have to change the below find to /opt/SecureSpan/Gateway/node/default/var/attachments/ instead.)

#!/bin/sh
#set -x
#export PATH=/bin:/usr/bin:/bin/sh
export PID=$(</opt/SecureSpan/Gateway/node/default/var/ssg.pid);
find /tmp/attachments/ -name "*" -type f -mmin +15 -delete

export deleted="ls -l /proc/$PID/fd 2> /dev/nul | grep deleted | sed -r \"s/.* ([0-9]+) \-.*/\/proc\/$PID\/fd\/\1/g\""
export listing=$(eval "$deleted")

for fn in $listing
do
    truncate -s 0 $fn
done

Schedule with crontab as required.


Ref:

Miscellaneous Cluster Properties (broadcom.com)

Change Gateway default log file location (broadcom.com)

Wednesday, November 20, 2019

Efficiently Purging Audits

Cleaning up the audit tables will release some disk space and may be required to shrink the database enough to perform the dump and sftp for a manual database re-sync when replication is broken. You should stop replication and run the commands on each node. DO NOT perform this if replication is broken and you do not intend to run the replication restart shell script, otherwise this may prevent automatic recovery by removing records that are referenced in pending relay logs.

Clean up the tables that have no constraints first to shorten the time between drop/add constraints:
truncate table audit_detail_params;
truncate table audit_message;
truncate table audit_admin;
truncate table audit_system;

Drop the constraints that block truncating other tables:
alter table audit_system drop foreign key `audit_system_ibfk_1`;
alter table audit_admin drop foreign key `audit_admin_ibfk_1`;
alter table audit_message drop foreign key `audit_message_ibfk_1`;
alter table audit_detail drop foreign key `audit_detail_ibfk_1`;
alter table audit_detail_params drop foreign key `audit_detail_params_ibfk_1`;

Truncate all the audit tables to be sure that there will be no records preventing re-adding the constraints:
truncate table audit_main;
truncate table audit_detail;
truncate table audit_detail_params;
truncate table audit_message;
truncate table audit_admin;
truncate table audit_system;

Re-add the constraints:
alter table audit_system add CONSTRAINT `audit_system_ibfk_1` FOREIGN KEY (`goid`) REFERENCES `audit_main` (`goid`) ON DELETE CASCADE ON UPDATE NO ACTION;
alter table audit_admin add CONSTRAINT `audit_admin_ibfk_1` FOREIGN KEY (`goid`) REFERENCES `audit_main` (`goid`) ON DELETE CASCADE ON UPDATE NO ACTION;
alter table audit_message add CONSTRAINT `audit_message_ibfk_1` FOREIGN KEY (`goid`) REFERENCES `audit_main` (`goid`) ON DELETE CASCADE ON UPDATE NO ACTION;
alter table audit_detail add CONSTRAINT `audit_detail_ibfk_1` FOREIGN KEY (`audit_goid`) REFERENCES `audit_main` (`goid`) ON DELETE CASCADE ON UPDATE NO ACTION;
alter table audit_detail_params add CONSTRAINT `audit_detail_params_ibfk_1` FOREIGN KEY (`audit_detail_goid`) REFERENCES `audit_detail` (`goid`) ON DELETE CASCADE ON UPDATE NO ACTION;

You can run all of these commands at once and more than once. If there is any errors on the re-add then run all the commands again.

Wednesday, April 12, 2017

Certificate Expiration Notification v9.1.0

This is an update to version 9.1.00 of the previous post (certificate-expiration-notification) that was written for version 8.1.02 of the gateway.  This update includes an authentication challenge (basic) which echos back to the requester whatever hostname they called to reach the gateway instead of the challenge realm sent by the require basic credentials assertion.  If you have read my other posts you will know that you can tailor that realm by editing the assertion in notepad, however it would still be hard coded and this is a more elegant dynamic solution (even though it's not particularly necessary in this service).  I've abstracted out the mailhost and email (used for from and bcc) into clusterwide properties so they can be set per environment without changing the policy itself.  In addition to sending a report to the gateway.cluster.email address it will also send individual notifications to email addresses of the users if that value has been set on their properties.  Aside from adding the email to the query results the shell script is unchanged (I couldn't recall if it was so I had to check, but technically the previous version should still work).

cd /opt/SecureSpan/Appliance/bin/
mysql -X -e "select c.user_id as uid,concat('FIP:',p.name) as repository,case when u.name is null then c.login else u.name end as name,u.email,c.cert as cert from ssg.client_cert as c left join ssg.identity_provider as p on c.provider = p.goid left join ssg.fed_user as u on unhex(c.user_id) = u.goid union select hex(goid) as uid,'Trusted Certificate' as repository,name,'' as email,cert_base64 as cert from ssg.trusted_cert;" > check.xml
curl -X POST -d @check.xml -H "Content-Type: application/xml; charset=utf-8" http://localhost:8080/parse_certs?days=60
rm -f check.xmlm -f check.xml

<?xml version="1.0" encoding="UTF-8"?>
<wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy">
    <wsp:All wsp:Usage="Required">
        <wsp:OneOrMore wsp:Usage="Required">
            <L7p:RemoteIpAddressRange>
                <L7p:NetworkMask intValue="1"/>
                <L7p:StartIp stringValue="127.0.0.1"/>
            </L7p:RemoteIpAddressRange>
            <wsp:All wsp:Usage="Required">
                <wsp:OneOrMore wsp:Usage="Required">
                    <L7p:SslAssertion/>
                    <wsp:All wsp:Usage="Required">
                        <L7p:AuditDetailAssertion>
                            <L7p:Detail stringValue="Client request was sent over unsecured HTTP"/>
                        </L7p:AuditDetailAssertion>
                        <L7p:CustomizeErrorResponse>
                            <L7p:ErrorLevel errorLevel="DROP_CONNECTION"/>
                            <L7p:ExtraHeaders nameValuePairArray="included"/>
                        </L7p:CustomizeErrorResponse>
                        <L7p:FalseAssertion/>
                    </wsp:All>
                </wsp:OneOrMore>
                <wsp:OneOrMore wsp:Usage="Required">
                    <wsp:All wsp:Usage="Required">
                        <L7p:SetVariable>
                            <L7p:Base64Expression stringValue="JHtyZXF1ZXN0Lmh0dHAuaGVhZGVyLmF1dGhvcml6YXRpb259"/>
                            <L7p:ContentType stringValue="text/xml; charset=utf-8"/>
                            <L7p:DataType variableDataType="message"/>
                            <L7p:VariableToSet stringValue="basic"/>
                        </L7p:SetVariable>
                        <L7p:Regex>
                            <L7p:AutoTarget booleanValue="false"/>
                            <L7p:OtherTargetMessageVariable stringValue="basic"/>
                            <L7p:Regex stringValue="\ABasic (.*)\Z"/>
                            <L7p:RegexName stringValue="trim 'Basic '"/>
                            <L7p:Replace booleanValue="true"/>
                            <L7p:Replacement stringValue="$1"/>
                            <L7p:Target target="OTHER"/>
                        </L7p:Regex>
                        <L7p:SetVariable>
                            <L7p:Base64Expression stringValue="JHtiYXNpYy5tYWlucGFydH0="/>
                            <L7p:VariableToSet stringValue="basic"/>
                        </L7p:SetVariable>
                        <L7p:EncodeDecode>
                            <L7p:SourceVariableName stringValue="basic"/>
                            <L7p:TargetDataType variableDataType="string"/>
                            <L7p:TargetVariableName stringValue="basic"/>
                            <L7p:TransformType transformType="BASE64_DECODE"/>
                        </L7p:EncodeDecode>
                        <L7p:Split>
                            <L7p:InputVariable stringValue="basic"/>
                            <L7p:OutputVariable stringValue="basic"/>
                            <L7p:SplitPattern stringValue=":"/>
                            <L7p:SplitPatternRegEx booleanValue="false"/>
                        </L7p:Split>
                        <L7p:ComparisonAssertion>
                            <L7p:CaseSensitive booleanValue="false"/>
                            <L7p:Expression1 stringValue="${basic}"/>
                            <L7p:Operator operatorNull="null"/>
                            <L7p:Predicates predicates="included">
                                <L7p:item dataType="included">
                                    <L7p:Type variableDataType="string"/>
                                </L7p:item>
                                <L7p:item binary="included">
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Negated booleanValue="true"/>
                                    <L7p:Operator operator="EMPTY"/>
                                    <L7p:RightValue stringValue=""/>
                                </L7p:item>
                            </L7p:Predicates>
                        </L7p:ComparisonAssertion>
                        <L7p:ComparisonAssertion>
                            <L7p:CaseSensitive booleanValue="false"/>
                            <L7p:Expression1 stringValue="${basic.length}"/>
                            <L7p:Operator operatorNull="null"/>
                            <L7p:Predicates predicates="included">
                                <L7p:item dataType="included">
                                    <L7p:Type variableDataType="int"/>
                                </L7p:item>
                                <L7p:item binary="included">
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Operator operator="GE"/>
                                    <L7p:RightValue stringValue="2"/>
                                </L7p:item>
                            </L7p:Predicates>
                        </L7p:ComparisonAssertion>
                        <L7p:HttpBasic/>
                    </wsp:All>
                    <wsp:All wsp:Usage="Required">
                        <L7p:CustomizeErrorResponse>
                            <L7p:AssertionComment assertionComment="included">
                                <L7p:Properties mapValue="included">
                                    <L7p:entry>
                                    <L7p:key stringValue="RIGHT.COMMENT"/>
                                    <L7p:value stringValue="// Authentication challenge response"/>
                                    </L7p:entry>
                                </L7p:Properties>
                            </L7p:AssertionComment>
                            <L7p:Content stringValue="Authentication Required"/>
                            <L7p:ContentType stringValue="text/plain;charset=utf-8"/>
                            <L7p:ExtraHeaders nameValuePairArray="included">
                                <L7p:item nameValuePair="included">
                                    <L7p:Key stringValue="WWW-Authenticate"/>
                                    <L7p:Value stringValue="Basic realm=&quot;${request.url.host}&quot;"/>
                                </L7p:item>
                            </L7p:ExtraHeaders>
                            <L7p:HttpStatus stringValue="401"/>
                        </L7p:CustomizeErrorResponse>
                        <L7p:FalseAssertion/>
                    </wsp:All>
                </wsp:OneOrMore>
                <L7p:Authentication>
                    <L7p:IdentityProviderOid goidValue="0000000000000000fffffffffffffffe"/>
                </L7p:Authentication>
            </wsp:All>
            <wsp:All wsp:Usage="Required">
                <L7p:CustomizeErrorResponse>
                    <L7p:AssertionComment assertionComment="included">
                        <L7p:Properties mapValue="included">
                            <L7p:entry>
                                <L7p:key stringValue="RIGHT.COMMENT"/>
                                <L7p:value stringValue="// SOAP"/>
                            </L7p:entry>
                        </L7p:Properties>
                    </L7p:AssertionComment>
                    <L7p:Content stringValueReference="inline"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <soapenv:Fault>
            <faultcode>soapenv:Client</faultcode>
            <faultstring>Access Denied</faultstring>
            <faultactor>${request.url}</faultactor>
            <detail>
                <datetime>${request.time}</datetime>
        </detail>
        </soapenv:Fault>
    </soapenv:Body>
</soapenv:Envelope>]]></L7p:Content>
                    <L7p:ContentType stringValue="text/xml;charset=utf-8"/>
                    <L7p:ExtraHeaders nameValuePairArray="included"/>
                    <L7p:HttpStatus stringValue="403"/>
                </L7p:CustomizeErrorResponse>
                <L7p:FalseAssertion/>
            </wsp:All>
            <L7p:assertionComment>
                <L7p:Properties mapValue="included">
                    <L7p:entry>
                        <L7p:key stringValue="RIGHT.COMMENT"/>
                        <L7p:value stringValue="//restriced to admin over https or localhost"/>
                    </L7p:entry>
                </L7p:Properties>
            </L7p:assertionComment>
        </wsp:OneOrMore>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="JHtnYXRld2F5LnRpbWV9"/>
            <L7p:DataType variableDataType="dateTime"/>
            <L7p:DateFormat stringValue="yyyy-MM-dd'T'HH:mm:ss.SSSX"/>
            <L7p:DateOffsetExpression stringValue="${request.http.parameter.days}"/>
            <L7p:DateOffsetField intValue="5"/>
            <L7p:VariableToSet stringValue="nextMonth"/>
        </L7p:SetVariable>
        <L7p:Regex>
            <L7p:AutoTarget booleanValue="false"/>
            <L7p:Regex stringValue="[\n\r]"/>
            <L7p:RegexName stringValue="remove line feed"/>
            <L7p:Replace booleanValue="true"/>
            <L7p:Replacement stringValue=""/>
        </L7p:Regex>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8Y2VydGlmaWNhdGVzIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiPg=="/>
            <L7p:ContentType stringValue="text/xml; charset=utf-8"/>
            <L7p:DataType variableDataType="message"/>
            <L7p:VariableToSet stringValue="response"/>
        </L7p:SetVariable>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="PGh0bWw+PGJvZHk+PHRhYmxlPg=="/>
            <L7p:ContentType stringValue="text/html; charset=utf-8"/>
            <L7p:DataType variableDataType="message"/>
            <L7p:VariableToSet stringValue="message"/>
        </L7p:SetVariable>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="JHttZXNzYWdlLm1haW5wYXJ0fQ0KICA8dHI+PHRkPm5hbWU8L3RkPg0KICAgICAgPHRkPnJlcG9zaXRvcnk8L3RkPg0KICAgICAgPHRkPnN1YmplY3Q8L3RkPg0KICAgICAgPHRkPmV4cGlyYXRpb248L3RkPg0KICAgICAgPHRkPnNlcmlhbDwvdGQ+DQogICAgICA8dGQ+dGh1bWJwcmludDwvdGQ+DQogICAgICA8dGQ+c2VsZlNpZ25lZDwvdGQ+DQogICAgICA8dGQ+Y2xpZW50PC90ZD4NCiAgICAgIDx0ZD5zZXJ2ZXI8L3RkPg0KICA8L3RyPg=="/>
            <L7p:ContentType stringValue="text/html; charset=utf-8"/>
            <L7p:DataType variableDataType="message"/>
            <L7p:VariableToSet stringValue="message"/>
        </L7p:SetVariable>
        <L7p:RequestXpathAssertion>
            <L7p:VariablePrefix stringValue="query"/>
            <L7p:XpathExpression xpathExpressionValue="included">
                <L7p:Expression stringValue="//field[@name='uid']"/>
                <L7p:Namespaces mapValue="included">
                    <L7p:entry>
                        <L7p:key stringValue="s"/>
                        <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                    </L7p:entry>
                    <L7p:entry>
                        <L7p:key stringValue="xsi"/>
                        <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                    </L7p:entry>
                </L7p:Namespaces>
                <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
            </L7p:XpathExpression>
        </L7p:RequestXpathAssertion>
        <L7p:ForEachLoop L7p:Usage="Required"
            loopVariable="query.results" variablePrefix="uid">
            <L7p:RequestXpathAssertion>
                <L7p:VariablePrefix stringValue="cert"/>
                <L7p:XpathExpression xpathExpressionValue="included">
                    <L7p:Expression stringValue="//row[field=$uid.current]/field[@name='cert']"/>
                    <L7p:Namespaces mapValue="included">
                        <L7p:entry>
                            <L7p:key stringValue="s"/>
                            <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                        </L7p:entry>
                        <L7p:entry>
                            <L7p:key stringValue="xsi"/>
                            <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                        </L7p:entry>
                    </L7p:Namespaces>
                    <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                </L7p:XpathExpression>
            </L7p:RequestXpathAssertion>
            <L7p:EncodeDecode>
                <L7p:CharacterEncoding stringValueNull="null"/>
                <L7p:SourceVariableName stringValue="cert.result"/>
                <L7p:TargetDataType variableDataType="cert"/>
                <L7p:TargetVariableName stringValue="cert"/>
                <L7p:TransformType transformType="BASE64_DECODE"/>
            </L7p:EncodeDecode>
            <L7p:SetVariable>
                <L7p:Base64Expression stringValue="JHtjZXJ0Lm5vdEFmdGVyfQ=="/>
                <L7p:DataType variableDataType="dateTime"/>
                <L7p:DateFormat stringValue="yyyy-MM-dd'T'HH:mm:ss.SSSX"/>
                <L7p:DateOffsetExpression stringValue="00"/>
                <L7p:VariableToSet stringValue="expiration"/>
            </L7p:SetVariable>
            <wsp:OneOrMore wsp:Usage="Required">
                <L7p:ComparisonAssertion>
                    <L7p:CaseSensitive booleanValue="false"/>
                    <L7p:Expression1 stringValue="${nextMonth}"/>
                    <L7p:Operator operatorNull="null"/>
                    <L7p:Predicates predicates="included">
                        <L7p:item dataType="included">
                            <L7p:Type variableDataType="dateTime"/>
                        </L7p:item>
                        <L7p:item binary="included">
                            <L7p:CaseSensitive booleanValue="false"/>
                            <L7p:Negated booleanValue="true"/>
                            <L7p:Operator operator="GT"/>
                            <L7p:RightValue stringValue="${expiration}"/>
                        </L7p:item>
                    </L7p:Predicates>
                </L7p:ComparisonAssertion>
                <wsp:All wsp:Usage="Required">
                    <L7p:RequestXpathAssertion>
                        <L7p:VariablePrefix stringValue="repository"/>
                        <L7p:XpathExpression xpathExpressionValue="included">
                            <L7p:Expression stringValue="//row[field=$uid.current]/field[@name='repository']"/>
                            <L7p:Namespaces mapValue="included">
                                <L7p:entry>
                                    <L7p:key stringValue="s"/>
                                    <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                                </L7p:entry>
                                <L7p:entry>
                                    <L7p:key stringValue="xsi"/>
                                    <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                                </L7p:entry>
                            </L7p:Namespaces>
                            <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                        </L7p:XpathExpression>
                    </L7p:RequestXpathAssertion>
                    <L7p:RequestXpathAssertion>
                        <L7p:VariablePrefix stringValue="name"/>
                        <L7p:XpathExpression xpathExpressionValue="included">
                            <L7p:Expression stringValue="//row[field=$uid.current]/field[@name='name']"/>
                            <L7p:Namespaces mapValue="included">
                                <L7p:entry>
                                    <L7p:key stringValue="s"/>
                                    <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                                </L7p:entry>
                                <L7p:entry>
                                    <L7p:key stringValue="xsi"/>
                                    <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                                </L7p:entry>
                            </L7p:Namespaces>
                            <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                        </L7p:XpathExpression>
                    </L7p:RequestXpathAssertion>
                    <wsp:All wsp:Usage="Required">
                        <wsp:OneOrMore wsp:Usage="Required">
                            <wsp:All wsp:Usage="Required">
                                <L7p:ComparisonAssertion>
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Expression1 stringValue="${cert.subject.dn}"/>
                                    <L7p:MultivaluedComparison multivaluedComparison="ANY"/>
                                    <L7p:Operator operatorNull="null"/>
                                    <L7p:Predicates predicates="included">
                                    <L7p:item dataType="included">
                                    <L7p:Type variableDataType="string"/>
                                    </L7p:item>
                                    <L7p:item binary="included">
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:RightValue stringValue="${cert.issuer.dn}"/>
                                    </L7p:item>
                                    </L7p:Predicates>
                                </L7p:ComparisonAssertion>
                                <L7p:SetVariable>
                                    <L7p:Base64Expression stringValue="dHJ1ZQ=="/>
                                    <L7p:VariableToSet stringValue="usage.root"/>
                                </L7p:SetVariable>
                            </wsp:All>
                            <L7p:SetVariable>
                                <L7p:Base64Expression stringValue="ZmFsc2U="/>
                                <L7p:VariableToSet stringValue="usage.root"/>
                            </L7p:SetVariable>
                            <L7p:assertionComment>
                                <L7p:Properties mapValue="included">
                                    <L7p:entry>
                                    <L7p:key stringValue="RIGHT.COMMENT"/>
                                    <L7p:value stringValue=" //usage.root"/>
                                    </L7p:entry>
                                </L7p:Properties>
                            </L7p:assertionComment>
                        </wsp:OneOrMore>
                        <L7p:SetVariable>
                            <L7p:Base64Expression stringValue="JHtjZXJ0LmtleVVzYWdlLmtleUVuY2lwaGVybWVudH0="/>
                           <L7p:VariableToSet stringValue="usage.client"/>
                        </L7p:SetVariable>
                        <L7p:SetVariable>
                            <L7p:Base64Expression stringValue="JHtjZXJ0LmtleVVzYWdlLmRpZ2l0YWxTaWduYXR1cmV9"/>
                            <L7p:VariableToSet stringValue="usage.server"/>
                        </L7p:SetVariable>
                        <wsp:OneOrMore wsp:Usage="Required">
                            <wsp:All wsp:Usage="Required">
                                <L7p:ComparisonAssertion>
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Expression1 stringValue="${cert.extendedKeyUsageValues}"/>
                                    <L7p:Operator operatorNull="null"/>
                                    <L7p:Predicates predicates="included">
                                    <L7p:item dataType="included">
                                    <L7p:Type variableDataType="string"/>
                                    </L7p:item>
                                    <L7p:item binary="included">
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Negated booleanValue="true"/>
                                    <L7p:Operator operator="EMPTY"/>
                                    <L7p:RightValue stringValue=""/>
                                    </L7p:item>
                                    </L7p:Predicates>
                                </L7p:ComparisonAssertion>
                                <L7p:SetVariable>
                                    <L7p:Base64Expression stringValue="Pg0KICAgICAgJHtjZXJ0LmV4dGVuZGVkS2V5VXNhZ2VWYWx1ZXN9DQogICAgPC9rZXlVc2FnZT4="/>
                                    <L7p:VariableToSet stringValue="usage.extended"/>
                                </L7p:SetVariable>
                            </wsp:All>
                            <L7p:SetVariable>
                                <L7p:Base64Expression stringValue="Lz4="/>
                                <L7p:VariableToSet stringValue="usage.extended"/>
                            </L7p:SetVariable>
                            <L7p:assertionComment>
                                <L7p:Properties mapValue="included">
                                    <L7p:entry>
                                    <L7p:key stringValue="RIGHT.COMMENT"/>
                                    <L7p:value stringValue=" //usage.extended"/>
                                    </L7p:entry>
                                </L7p:Properties>
                            </L7p:assertionComment>
                        </wsp:OneOrMore>
                        <L7p:assertionComment>
                            <L7p:Properties mapValue="included">
                                <L7p:entry>
                                    <L7p:key stringValue="RIGHT.COMMENT"/>
                                    <L7p:value stringValue="//cert.usage"/>
                                </L7p:entry>
                            </L7p:Properties>
                        </L7p:assertionComment>
                    </wsp:All>
                    <L7p:SetVariable>
                        <L7p:Base64Expression stringValue="JHtyZXNwb25zZS5tYWlucGFydH0NCiAgPGNlcnQgdWlkPSIke3VpZC5jdXJyZW50fSIgbmFtZT0iJHtuYW1lLnJlc3VsdH0iIHJlcG9zaXRvcnk9IiR7cmVwb3NpdG9yeS5yZXN1bHR9Ij4NCiAgICA8c3ViamVjdENOPiR7Y2VydC5zdWJqZWN0LmRuLmNufTwvc3ViamVjdENOPg0KICAgIDxzdWJqZWN0RE4+JHtjZXJ0LnN1YmplY3R9PC9zdWJqZWN0RE4+DQogICAgPGV4cGlyYXRpb24+JHtjZXJ0Lm5vdEFmdGVyfTwvZXhwaXJhdGlvbj4NCiAgICA8c2VyaWFsPiR7Y2VydC5zZXJpYWx9PC9zZXJpYWw+DQogICAgPHRodW1icHJpbnQ+JHtjZXJ0LnRodW1icHJpbnRTSEExfTwvdGh1bWJwcmludD4NCiAgICA8a2V5VXNhZ2Ugc2VsZlNpZ25lZD0iJHt1c2FnZS5yb290fSINCiAgICAgICAgICAgICAgY2xpZW50PSIke3VzYWdlLmNsaWVudH0iDQogICAgICAgICAgICAgIHNlcnZlcj0iJHt1c2FnZS5zZXJ2ZXJ9Ig0KICAgICAgJHt1c2FnZS5leHRlbmRlZH0NCiAgICA8aXNzdWVyPiR7Y2VydC5pc3N1ZXIuZG59PC9pc3N1ZXI+DQogICAgPFg1MDk+JHtjZXJ0LmJhc2U2NH08L1g1MDk+DQogIDwvY2VydD4="/>
                        <L7p:ContentType stringValue="text/xml; charset=utf-8"/>
                        <L7p:DataType variableDataType="message"/>
                        <L7p:VariableToSet stringValue="response"/>
                    </L7p:SetVariable>
                    <L7p:SetVariable>
                        <L7p:Base64Expression stringValue="JHttZXNzYWdlLm1haW5wYXJ0fQ0KICA8dHI+PHRkPiR7bmFtZS5yZXN1bHR9PC90ZD4NCiAgICAgIDx0ZD4ke3JlcG9zaXRvcnkucmVzdWx0fTwvdGQ+DQogICAgICA8dGQ+JHtjZXJ0LnN1YmplY3QuZG4uY259PC90ZD4NCiAgICAgIDx0ZD4ke2NlcnQubm90QWZ0ZXJ9PC90ZD4NCiAgICAgIDx0ZD4ke2NlcnQuc2VyaWFsfTwvdGQ+DQogICAgICA8dGQ+JHtjZXJ0LnRodW1icHJpbnRTSEExfTwvdGQ+DQogICAgICA8dGQ+JHt1c2FnZS5yb290fTwvdGQ+DQogICAgICA8dGQ+JHt1c2FnZS5jbGllbnR9PC90ZD4NCiAgICAgIDx0ZD4ke3VzYWdlLnNlcnZlcn08L3RkPg0KICA8L3RyPg=="/>
                        <L7p:ContentType stringValue="text/html; charset=utf-8"/>
                        <L7p:DataType variableDataType="message"/>
                        <L7p:VariableToSet stringValue="message"/>
                    </L7p:SetVariable>
                    <wsp:OneOrMore wsp:Usage="Required">
                        <wsp:All wsp:Usage="Required">
                            <L7p:RequestXpathAssertion>
                                <L7p:VariablePrefix stringValue="email"/>
                                <L7p:XpathExpression xpathExpressionValue="included">
                                    <L7p:Expression stringValue="//row[field=$uid.current]/field[@name='email']"/>
                                    <L7p:Namespaces mapValue="included">
                                    <L7p:entry>
                                    <L7p:key stringValue="s"/>
                                    <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                                    </L7p:entry>
                                    <L7p:entry>
                                    <L7p:key stringValue="xsi"/>
                                    <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                                    </L7p:entry>
                                    </L7p:Namespaces>
                                    <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                                </L7p:XpathExpression>
                            </L7p:RequestXpathAssertion>
                            <L7p:ComparisonAssertion>
                                <L7p:CaseSensitive booleanValue="false"/>
                                <L7p:Expression1 stringValue="${email.result}"/>
                                <L7p:Operator operatorNull="null"/>
                                <L7p:Predicates predicates="included">
                                    <L7p:item dataType="included">
                                    <L7p:Type variableDataType="string"/>
                                    </L7p:item>
                                    <L7p:item binary="included">
                                    <L7p:CaseSensitive booleanValue="false"/>
                                    <L7p:Negated booleanValue="true"/>
                                    <L7p:Operator operator="EMPTY"/>
                                    <L7p:RightValue stringValue=""/>
                                    </L7p:item>
                                </L7p:Predicates>
                            </L7p:ComparisonAssertion>
                            <wsp:OneOrMore wsp:Usage="Required">
                                <L7p:EmailAlert>
                                    <L7p:Base64message stringValue="U3ViamVjdDogJHtjZXJ0LnN1YmplY3QuZG4uY259Cklzc3VlZCBCeTogJHtjZXJ0Lmlzc3Vlci5kbn0KRXhwaXJhdGlvbjogJHtjZXJ0Lm5vdEFmdGVyfQpTZXJpYWwgTnVtYmVyOiAke2NlcnQuc2VyaWFsfQpUaHVtYnByaW50OiAke2NlcnQudGh1bWJwcmludFNIQTF9"/>
                                    <L7p:SmtpHost stringValue="${gateway.mailhost}"/>
                                    <L7p:SourceEmailAddress stringValue="${gateway.cluster.hostname} &lt;${gateway.cluster.email}>"/>
                                    <L7p:Subject stringValue="Your ${repository.result} is due to expire soon"/>
                                    <L7p:TargetBCCEmailAddress stringValue="${gateway.cluster.email}"/>
                                    <L7p:TargetEmailAddress stringValue="${email.result}"/>
                                </L7p:EmailAlert>
                                <L7p:EmailAlert>
                                    <L7p:Base64message stringValue="U3ViamVjdDogJHtjZXJ0LnN1YmplY3QuZG4uY259Cklzc3VlZCBCeTogJHtjZXJ0Lmlzc3Vlci5kbn0KRXhwaXJhdGlvbjogJHtjZXJ0Lm5vdEFmdGVyfQpTZXJpYWwgTnVtYmVyOiAke2NlcnQuc2VyaWFsfQpUaHVtYnByaW50OiAke2NlcnQudGh1bWJwcmludFNIQTF9"/>
                                    <L7p:SmtpHost stringValue="${gateway.mailhost}"/>
                                    <L7p:SourceEmailAddress stringValue="${gateway.cluster.hostname} &lt;${gateway.cluster.email}>"/>
                                    <L7p:Subject stringValue="Unable to deliver &quot;Your ${repository.result} is due to expire soon&quot; To: ${email.result}"/>
                                    <L7p:TargetEmailAddress stringValue="${gateway.cluster.email}"/>
                                </L7p:EmailAlert>
                            </wsp:OneOrMore>
                        </wsp:All>
                        <L7p:TrueAssertion/>
                    </wsp:OneOrMore>
                </wsp:All>
            </wsp:OneOrMore>
        </L7p:ForEachLoop>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="JHtyZXNwb25zZS5tYWlucGFydH0NCjwvY2VydGlmaWNhdGVzPg=="/>
            <L7p:ContentType stringValue="application/xml; charset=utf-8"/>
            <L7p:DataType variableDataType="message"/>
            <L7p:VariableToSet stringValue="response"/>
        </L7p:SetVariable>
        <L7p:SetVariable>
            <L7p:Base64Expression stringValue="JHttZXNzYWdlLm1haW5wYXJ0fQ0KPC90YWJsZT48L2JvZHk+PC9odG1sPg=="/>
            <L7p:ContentType stringValue="text/html; charset=utf-8"/>
            <L7p:DataType variableDataType="message"/>
            <L7p:VariableToSet stringValue="message"/>
        </L7p:SetVariable>
        <wsp:OneOrMore wsp:Usage="Required">
            <L7p:ResponseXpathAssertion>
                <L7p:VariablePrefix stringValue="query"/>
                <L7p:XmlMsgSrc stringValue="response"/>
                <L7p:XpathExpression xpathExpressionValue="included">
                    <L7p:Expression stringValue="//cert/@uid"/>
                    <L7p:Namespaces mapValue="included">
                        <L7p:entry>
                            <L7p:key stringValue="s"/>
                            <L7p:value stringValue="http://schemas.xmlsoap.org/soap/envelope/"/>
                        </L7p:entry>
                        <L7p:entry>
                           <L7p:key stringValue="xsi"/>
                            <L7p:value stringValue="http://www.w3.org/2001/XMLSchema-instance"/>
                        </L7p:entry>
                    </L7p:Namespaces>
                    <L7p:XpathVersion xpathVersion="XPATH_1_0"/>
                </L7p:XpathExpression>
            </L7p:ResponseXpathAssertion>
            <L7p:SetVariable>
                <L7p:Base64Expression stringValue="PGNlcnRpZmljYXRlcyB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIj4NCiAgbm8gdXBjb21pbmcgZXhwaXJhdGlvbnMNCjwvY2VydGlmaWNhdGVzPg=="/>
                <L7p:ContentType stringValue="application/xml; charset=utf-8"/>
                <L7p:DataType variableDataType="message"/>
                <L7p:VariableToSet stringValue="response"/>
            </L7p:SetVariable>
        </wsp:OneOrMore>
        <L7p:EmailAlert>
            <L7p:Base64message stringValue="JHttZXNzYWdlLm1haW5wYXJ0fQ=="/>
            <L7p:SmtpHost stringValue="${gateway.mailhost}"/>
            <L7p:SourceEmailAddress stringValue="${gateway.cluster.hostname} &lt;${gateway.cluster.email}>"/>
            <L7p:Subject stringValue="The following certificates will expire within the next ${request.http.parameter.days} days"/>
            <L7p:TargetEmailAddress stringValue="${gateway.cluster.email}"/>
        </L7p:EmailAlert>
        <L7p:HardcodedResponse>
            <L7p:Base64ResponseBody stringValue="ZW1haWwgc2VudA=="/>
            <L7p:ResponseContentType stringValue="text/plain; charset=UTF-8"/>
        </L7p:HardcodedResponse>
    </wsp:All>
</wsp:Policy>