Subject: | XPath verify does not report problems when using Schema file and message string |
I am using a schema file (SwSec.xsd) which imports other schemas
(attached) and, no matter what I pass to it for a message, it passes
validation. dbg... and screen... files contain script output.
b.pl is a small sample for me to test with. StatSchema.pm has the
references to Schematron.
Subject: | Sw.xsd |
Message body is not shown because it is too large.
Subject: | SwInt.xsd |
Message body is not shown because it is too large.
Subject: | SwGbl.xsd |
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by SWIFTStandards Workstation (build:R5.1.0.4) on 2006 Mar 13 13:56:07-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:swift:snl:ns.SwGbl" targetNamespace="urn:swift:snl:ns.SwGbl" elementFormDefault="qualified">
<xs:element name="Severity" type="PCDATA"/>
<xs:element name="Code" type="PCDATA"/>
<xs:element name="Parameter" type="Any"/>
<xs:element name="Text" type="PCDATA"/>
<xs:element name="Action" type="PCDATA"/>
<xs:element name="Details" type="Details"/>
<xs:complexType name="Any" mixed="true">
<xs:sequence>
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Details">
<xs:sequence>
<xs:element name="Code" type="PCDATA"/>
<xs:element name="Text" type="PCDATA" minOccurs="0"/>
<xs:element name="Action" type="PCDATA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="PCDATA">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:complexType name="Status">
<xs:sequence>
<xs:element name="StatusAttributes" type="StatusAttributes" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="StatusAttributes">
<xs:sequence>
<xs:element name="Severity" type="PCDATA"/>
<xs:element name="Code" type="PCDATA"/>
<xs:element name="Parameter" type="Any" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="Text" type="PCDATA" minOccurs="0"/>
<xs:element name="Action" type="PCDATA" minOccurs="0"/>
<xs:element name="Details" type="Details" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:element name="Status" type="Status"/>
<xs:element name="StatusAttributes" type="StatusAttributes"/>
</xs:schema>
Subject: | screen_output.txt |
cuhpsv33:bmills:SPIAT:PAC_SWNET:/home/bmills> b.pl --client host@r:cuhppc037
10:47:23 03/23/2006 | User "bmills" | Script"./b.pl" | PID 13641 | Perl 5.006001
Script parameters: "--client" "host@r:cuhppc037"
ROOT - SwSec:CreateContextRequest
SCHEMA - SwSec.xsd
SCHEMAPATH - /tdserver/data/SNL/SCHEMA/5.0.15/SwSec.xsd
10:47:25 03/23/2006 | high | | Validation Result: success at validated
ROOT - SwSec:CreateContextRequest
SCHEMA - SwSec.xsd
SCHEMAPATH - /tdserver/data/SNL/SCHEMA/5.0.15/SwSec.xsd
10:47:25 03/23/2006 | high | | Validation Result: success at validated
10:47:25 03/23/2006 | User "bmills" | Duration 2 secs
Results: 2 successes, 0 warnings, 0 fails
Script "b.pl" PASSED
cuhpsv33:bmills:SPIAT:PAC_SWNET:/home/bmills>
Subject: | dbg.b.032306104723 |
10:47:23 03/23/2006 | User "bmills" | Script"./b.pl" | PID 13641 | Perl 5.006001
Script parameters: "--client" "host@r:cuhppc037"
10:47:25 03/23/2006 | low | | PASS = 1
10:47:25 03/23/2006 | high | | Validation Result: success at validated
10:47:25 03/23/2006 | low | | PASS = 1
10:47:25 03/23/2006 | high | | Validation Result: success at validated
10:47:25 03/23/2006 | User "bmills" | Duration 2 secs
Results: 2 successes, 0 warnings, 0 fails
Script "b.pl" PASSED
Subject: | b.pl |
#!/usr/bin/perl -w
use StatConfig;
use StatSchema;
use StatEvidence;
my $rule = stGetRules( GroupName => "STATTEST" );
my $goodmsg = '<?xml version="1.0"?>
<!DOCTYPE SwSec:CreateContextRequest SYSTEM "SwPrimitive.dtd">
<SwSec:CreateContextRequest>
<SwSec:FileName>win2KSA</SwSec:FileName>
<SwSec:Password>pacus_123</SwSec:Password>
<SwSec:Sign>TRUE</SwSec:Sign>
<SwSec:Decrypt>TRUE</SwSec:Decrypt>
<SwSec:Authorisation>TRUE</SwSec:Authorisation>
</SwSec:CreateContextRequest>';
my $badmsg = '<?xml version="1.0"?>
<!DOCTYPE SwSec:CreateContextRequest SYSTEM "SwPrimitive.dtd">
<SwSec:CreateContextRequest>
<SwSec:Password>pacus_123</SwSec:Password>
<SwSec:Sign>TRUE</SwSec:Sign>
<SwSec:Decrypt>TRUE</SwSec:Decrypt>
<SwSec:Authorisation>TRUE</SwSec:Authorisation>
</SwSec:CreateContextRequest>';
my ($pass,@errors) = stSchemaValidate( Rule => $rule, Message => $goodmsg );
stAppendLog(Level => 'low', Text => "PASS = $pass, ERRORS = @errors" ) unless $pass;
stAppendLog(Level => 'low', Text => "PASS = $pass" ) if $pass;
stValidate(Value => scalar($pass == 1), Label => "validated" );
($pass,@errors) = stSchemaValidate( Rule => $rule, Message => $badmsg );
stAppendLog(Level => 'low', Text => "PASS = $pass, ERRORS = @errors" ) unless $pass;
stAppendLog(Level => 'low', Text => "PASS = $pass" ) if $pass;
stValidate(Value => scalar($pass == 1), Label => "validated" );
Subject: | SwSec.xsd |
<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by SWIFTStandards Workstation (build:R5.1.0.4) on 2006 Mar 13 13:56:07-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:swift:snl:ns.SwSec" xmlns:SwGbl="urn:swift:snl:ns.SwGbl" xmlns:Sw="urn:swift:snl:ns.Sw" targetNamespace="urn:swift:snl:ns.SwSec" elementFormDefault="qualified">
<xs:import namespace="urn:swift:snl:ns.SwGbl" schemaLocation="SwGbl.xsd"/>
<xs:import namespace="urn:swift:snl:ns.Sw" schemaLocation="Sw.xsd"/>
<xs:element name="FileName" type="PCDATA"/>
<xs:element name="Password" type="PCDATA"/>
<xs:element name="Sign" type="PCDATA"/>
<xs:element name="Decrypt" type="PCDATA"/>
<xs:element name="Authorisation" type="PCDATA"/>
<xs:element name="CryptoControl" type="CryptoControl"/>
<xs:element name="CryptoInfo" type="CryptoInfo"/>
<xs:element name="CryptoDescriptor" type="CryptoDescriptor"/>
<xs:element name="CryptoUserInfo" type="Any"/>
<xs:element name="MemberRef" type="PCDATA"/>
<xs:element name="EncryptDN" type="PCDATA"/>
<xs:element name="SecurityContext" type="SecurityContext"/>
<xs:element name="CertPolicyId" type="PCDATA"/>
<xs:element name="SecToSecureData" type="Any"/>
<xs:element name="SignedInfo" type="SignedInfo"/>
<xs:element name="KeyInfo" type="KeyInfo"/>
<xs:element name="Manifest" type="Manifest"/>
<xs:element name="Signature" type="Signature"/>
<xs:element name="SwiftVerifiedRevocation" type="PCDATA"/>
<xs:element name="SecUnsecuredData" type="Any"/>
<xs:complexType name="Any" mixed="true">
<xs:sequence>
<xs:any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CreateContextRequest">
<xs:sequence>
<xs:element name="FileName" type="PCDATA"/>
<xs:element name="Password" type="PCDATA"/>
<xs:element name="Sign" type="PCDATA"/>
<xs:element name="Decrypt" type="PCDATA"/>
<xs:element name="Authorisation" type="PCDATA"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CreateContextResponse">
<xs:sequence>
<xs:element name="SecurityContext" type="SecurityContext" minOccurs="0"/>
<xs:element name="CertPolicyId" type="PCDATA" minOccurs="0"/>
<xs:element ref="SwGbl:Status" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Crypto">
<xs:sequence>
<xs:choice>
<xs:element name="CryptoControl" type="CryptoControl"/>
<xs:sequence>
<xs:element name="CryptoInternal" type="Any"/>
<xs:choice>
<xs:element name="CryptoInfo" type="CryptoInfo"/>
<xs:element name="CryptoDescriptor" type="CryptoDescriptor"/>
</xs:choice>
</xs:sequence>
<xs:element name="CryptoDescriptor" type="CryptoDescriptor"/>
</xs:choice>
<xs:element name="CryptoUserInfo" type="Any" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CryptoControl">
<xs:sequence>
<xs:element name="MemberRef" type="PCDATA" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="EncryptDN" type="PCDATA" minOccurs="0"/>
<xs:element name="SignDN" type="PCDATA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CryptoDescriptor">
<xs:sequence>
<xs:element name="MemberRef" type="PCDATA" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="EncryptDN" type="PCDATA" minOccurs="0"/>
<xs:element name="SignDN" type="PCDATA" minOccurs="0"/>
<xs:element name="CertPolicyId" type="PCDATA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="CryptoInfo">
<xs:sequence>
<xs:element name="MemberRef" type="PCDATA" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="EncryptDN" type="PCDATA" minOccurs="0"/>
<xs:element name="SignDN" type="PCDATA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DestroyContextRequest">
<xs:sequence>
<xs:element name="SecurityContext" type="SecurityContext"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="DestroyContextResponse">
<xs:sequence>
<xs:element ref="SwGbl:Status" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="KeyInfo">
<xs:sequence>
<xs:element name="SignDN" type="PCDATA"/>
<xs:element name="CertPolicyId" type="PCDATA" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Manifest">
<xs:sequence>
<xs:element ref="Sw:Reference" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="PCDATA">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:complexType name="SecurityContext">
<xs:sequence>
<xs:element name="UserDN" type="PCDATA"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SignEncryptRequest">
<xs:sequence>
<xs:element name="AuthorisationContext" type="SecurityContext"/>
<xs:element name="SecToSecureData" type="Any"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SignEncryptResponse">
<xs:sequence>
<xs:element name="SecSecuredData" type="Any" minOccurs="0"/>
<xs:element ref="SwGbl:Status" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Signature">
<xs:sequence>
<xs:element name="SignedInfo" type="SignedInfo" minOccurs="0"/>
<xs:element name="SignatureValue" type="PCDATA" minOccurs="0"/>
<xs:element name="KeyInfo" type="KeyInfo"/>
<xs:element name="Manifest" type="Manifest"/>
<xs:element ref="Sw:Object" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SignatureList">
<xs:sequence>
<xs:element name="Signature" type="Signature" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="SignedInfo">
<xs:sequence>
<xs:element ref="Sw:Reference"/>
</xs:sequence>
</xs:complexType>
<xs:element name="AuthorisationContext" type="SecurityContext"/>
<xs:element name="Crypto" type="Crypto"/>
<xs:element name="SignatureList" type="SignatureList"/>
<xs:element name="CipherKey" type="PCDATA"/>
<xs:element name="CipherText" type="PCDATA"/>
<xs:element name="CryptoProtocol" type="PCDATA"/>
<xs:element name="CreateContextRequest" type="CreateContextRequest"/>
<xs:element name="CreateContextResponse" type="CreateContextResponse"/>
<xs:element name="DestroyContextRequest" type="DestroyContextRequest"/>
<xs:element name="DestroyContextResponse" type="DestroyContextResponse"/>
<xs:element name="SignEncryptRequest" type="SignEncryptRequest"/>
<xs:element name="SignEncryptResponse" type="SignEncryptResponse"/>
<xs:element name="VerifyDecryptRequest" type="VerifyDecryptRequest"/>
<xs:element name="VerifyDecryptResponse" type="VerifyDecryptResponse"/>
<xs:element name="SecSecuredData" type="Any"/>
<xs:element name="CryptoInternal" type="Any"/>
<xs:element name="SignatureValue" type="PCDATA"/>
<xs:element name="UserDN" type="PCDATA"/>
<xs:element name="SignDN" type="PCDATA"/>
<xs:complexType name="VerifyDecryptRequest">
<xs:sequence>
<xs:element name="AuthorisationContext" type="SecurityContext"/>
<xs:element name="SwiftVerifiedRevocation" type="PCDATA" minOccurs="0"/>
<xs:element name="SecSecuredData" type="Any"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="VerifyDecryptResponse">
<xs:sequence>
<xs:element name="SecUnsecuredData" type="Any" minOccurs="0"/>
<xs:element ref="SwGbl:Status" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Subject: | StatSchema.pm |
# $Header: $
package StatSchema;
###################################################################################################################
=begin module_comment
<Module Name="StatSchema.pm" Author="B. Mills">
<Description>This module contains subprocess to handle SNL Schema Validation.</Description>
<Subprocess Privacy="Public">stSchemaValidate</Subprocess>
<History Date="22-Mar-2006" Author="B. Mills">Initial creation</History>
</Module>
=end module_comment
=cut;
###################################################################################################################
use strict;
use Carp;
use StatUtil;
use StatConfig;
use StatEvidence;
use XML::Ximple (qw( parse_xml get_root_tag ) );
use XML::Schematron::XPath;
require Exporter;
our @ISA=qw(Exporter);
our @EXPORT=qw(stSchemaValidate);
my $SCHEMA_PATH = '/tdserver/data/SNL/SCHEMA';
my $VERSION;
my @codes = ();
###################################################################################################################
=begin api_comment
<Subprocess Name="stSchemaValidate" Author="B. Mills">
<Description>Finds the information from rule and message to properly validate the message against the Schema.
NOTE: Either Rule or Host must be specified. If both are specified, Host ONLY WILL BE USED!!</Description>
<Parameter Name="Rule" Mandatory="No"/>
<Parameter Name="Host" Mandatory="No">
<Description>Can be Host string or Host Object</Description>
</Parameter>
<Parameter Name="Message" Mandatory="Yes"/>
<ReturnValue Name="Valid">
<Description>Either 1 for valid or 0 for invalid unless error not Schema related</Description>
</ReturnValue>
<ReturnValue Name="Error">
<Description>Error produced (if any)</Description>
</ReturnValue>
<History Date="22-Mar-2006" Author="B. Mills">Initial Creation</History>
<Sample>my ($result, $errcode) = stSchemaValidate( Rule => $rule, Message => $response );</Sample>
<Sample>my ($result, $errcode) = stSchemaValidate( Host => $host, Message => $response );</Sample>
</Subprocess>
=end api_comment
=cut;
###################################################################################################################
sub stSchemaValidate {
my %args=@_;
StatUtil::ValidateParams ( { 'Rule' => undef,
'Host' => undef,
'Message' => StatUtil::PARAM_Mandatory }, \%args );
my $msg = $args{'Message'};
my @result = ();
@codes = ();
StatEvidence::stAppendLog( Level => 'medium',
Text => "Both Rule and Host specified, Host will be used" )
if ( defined $args{'Rule'} && defined $args{'Host'} );
return ( -996, "Either Rule or Host MUST BE SPECIFIED, NO VALIDATION" ) unless ( defined $args{'Rule'} || defined $args{'Host'} );
my $xmltree = parse_xml( $msg );
my $root = get_root_tag( $xmltree )->{tag_name};
my ($schema) = $root =~ /([A-Za-z]+):/;
$schema .= ".xsd";
print "ROOT - $root\n";
print "SCHEMA - $schema\n";
if ( defined $args{'Rule'} ) {
my $rule = $args{'Rule'};
if ( $root =~ /Handle/ ) {
#use responder SNL release directory
$VERSION = $rule->stGetResponder()->stGetSNL()->stGetHost()->stGetRelease()->stGetVersion();
} else {
#use requestor SNL release directory
$VERSION = $rule->stGetRequestorHost()->stGetRelease()->stGetVersion();
}
}
if ( defined $args{'Host'} ) {
my $host = $args{'Host'};
$host = stGetHosts( HostName => $host ) unless StatUtil::isa( $host, 'StatConfig::Host' );
$VERSION = $host->stGetRelease()->stGetVersion();
}
return ( -998, "$schema not found for Release $VERSION" )
if ( ! -e $SCHEMA_PATH . '/' . $VERSION . '/' . $schema );
my $schema_path = $SCHEMA_PATH . '/' . $VERSION . '/' . $schema;
print "SCHEMAPATH - $schema_path\n";
my $pseudotron = XML::Schematron::XPath->new( schema => $schema_path );
my $errors = $pseudotron->verify( $msg );
print "ERRORS - $errors\n" if $errors;
$errors ? return( 0, $errors ) : return( 1, undef );
# my $validator = XML::Validator::Schema->new( file => $schema_path );
# my $parser = XML::SAX::ParserFactory->parser( Handler => $validator );
# eval { $parser->parse_string( $msg ) };
# my %counts = ();
#get data from hash and return value based on that
# foreach my $code (@codes) {
# $counts{$code}++;
# }
# @codes ? return ( 0, %counts ) : return ( 1, undef );
}
1;