Mercurial > repos > ktnyt > gembassy
comparison GEMBASSY-1.0.3/gsoap/wsdl/wsp.cpp @ 2:8947fca5f715 draft default tip
Uploaded
| author | ktnyt |
|---|---|
| date | Fri, 26 Jun 2015 05:21:44 -0400 |
| parents | 84a17b3fad1f |
| children |
comparison
equal
deleted
inserted
replaced
| 1:84a17b3fad1f | 2:8947fca5f715 |
|---|---|
| 1 /* | |
| 2 wsp.cpp | |
| 3 | |
| 4 WS-Policy 1.2 and 1.5 binding schema | |
| 5 | |
| 6 -------------------------------------------------------------------------------- | |
| 7 gSOAP XML Web services tools | |
| 8 Copyright (C) 2001-2010, Robert van Engelen, Genivia Inc. All Rights Reserved. | |
| 9 This software is released under one of the following licenses: | |
| 10 GPL or Genivia's license for commercial use. | |
| 11 -------------------------------------------------------------------------------- | |
| 12 GPL license. | |
| 13 | |
| 14 This program is free software; you can redistribute it and/or modify it under | |
| 15 the terms of the GNU General Public License as published by the Free Software | |
| 16 Foundation; either version 2 of the License, or (at your option) any later | |
| 17 version. | |
| 18 | |
| 19 This program is distributed in the hope that it will be useful, but WITHOUT ANY | |
| 20 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
| 21 PARTICULAR PURPOSE. See the GNU General Public License for more details. | |
| 22 | |
| 23 You should have received a copy of the GNU General Public License along with | |
| 24 this program; if not, write to the Free Software Foundation, Inc., 59 Temple | |
| 25 Place, Suite 330, Boston, MA 02111-1307 USA | |
| 26 | |
| 27 Author contact information: | |
| 28 engelen@genivia.com / engelen@acm.org | |
| 29 -------------------------------------------------------------------------------- | |
| 30 A commercial use license is available from Genivia, Inc., contact@genivia.com | |
| 31 -------------------------------------------------------------------------------- | |
| 32 */ | |
| 33 | |
| 34 #include "wsdlH.h" | |
| 35 #include "includes.h" | |
| 36 #include "types.h" | |
| 37 #include "service.h" | |
| 38 | |
| 39 static wsp__Policy *search(const char *URI, wsdl__definitions& definitions); | |
| 40 static wsp__Policy *search(const char *URI, wsp__Policy *policy); | |
| 41 static wsp__Policy *search(const char *URI, wsp__Content *content); | |
| 42 static void gen_parts(const sp__Parts& parts, Types& types, const char *what, const char *name, int indent); | |
| 43 | |
| 44 //////////////////////////////////////////////////////////////////////////////// | |
| 45 // | |
| 46 // wsp:OperatorContentType | |
| 47 // | |
| 48 //////////////////////////////////////////////////////////////////////////////// | |
| 49 | |
| 50 int wsp__Content::traverse(wsdl__definitions& definitions) | |
| 51 { if (vflag) | |
| 52 cerr << " Analyzing wsp Policy" << endl; | |
| 53 if (Policy) | |
| 54 Policy->traverse(definitions); | |
| 55 if (PolicyReference) | |
| 56 PolicyReference->traverse(definitions); | |
| 57 for (vector<wsp__Content*>::iterator i = All.begin(); i != All.end(); ++i) | |
| 58 { if (*i) | |
| 59 (*i)->traverse(definitions); | |
| 60 } | |
| 61 for (vector<wsp__Content*>::iterator j = ExactlyOne.begin(); j != ExactlyOne.end(); ++j) | |
| 62 { if (*j) | |
| 63 (*j)->traverse(definitions); | |
| 64 } | |
| 65 return SOAP_OK; | |
| 66 } | |
| 67 | |
| 68 void wsp__Content::generate(Service& service, Types& types, int indent) const | |
| 69 { static const char stabs[] = "\t\t\t\t\t\t\t\t\t\t"; | |
| 70 const char *tabs; | |
| 71 if (indent > 8) | |
| 72 indent = 8; | |
| 73 tabs = stabs + 9 - indent; | |
| 74 // Recursive policies and references | |
| 75 if (Policy) | |
| 76 Policy->generate(service, types, indent); | |
| 77 if (PolicyReference && PolicyReference->policyPtr()) | |
| 78 PolicyReference->policyPtr()->generate(service, types, indent); | |
| 79 // WS-Policy All | |
| 80 if (!All.empty()) | |
| 81 { fprintf(stream, "%s- All of the following:\n", tabs); | |
| 82 for (vector<wsp__Content*>::const_iterator p = All.begin(); p != All.end(); ++p) | |
| 83 if (*p) | |
| 84 (*p)->generate(service, types, indent + 1); | |
| 85 } | |
| 86 // WS-Policy ExactlyOne | |
| 87 if (!ExactlyOne.empty()) | |
| 88 { fprintf(stream, "%s- Exactly one of the following:\n", tabs); | |
| 89 for (vector<wsp__Content*>::const_iterator p = ExactlyOne.begin(); p != ExactlyOne.end(); ++p) | |
| 90 if (*p) | |
| 91 (*p)->generate(service, types, indent + 1); | |
| 92 } | |
| 93 // WS-SecurityPolicy Parts (TODO: do we need vectors of these?) | |
| 94 for (vector<sp__Parts>::const_iterator sp = sp__SignedParts.begin(); sp != sp__SignedParts.end(); ++sp) | |
| 95 gen_parts(*sp, types, "sign", "[4.1.1] WS-Security Signed Parts", indent); | |
| 96 for (vector<sp__Parts>::const_iterator ep = sp__EncryptedParts.begin(); ep != sp__EncryptedParts.end(); ++ep) | |
| 97 gen_parts(*ep, types, "encrypt", "[4.2.1] Security Encrypted Parts", indent); | |
| 98 for (vector<sp__Parts>::const_iterator rp = sp__RequiredParts.begin(); rp != sp__RequiredParts.end(); ++rp) | |
| 99 { fprintf(stream, "%s- Required Header elements:", tabs); | |
| 100 for (vector<sp__Header>::const_iterator h = (*rp).Header.begin(); h != (*rp).Header.end(); ++h) | |
| 101 if ((*h).Name) | |
| 102 fprintf(stream, " %s", types.aname(NULL, (*h).Namespace, (*h).Name)); | |
| 103 else if ((*h).Namespace) | |
| 104 fprintf(stream, " %s", (*h).Namespace); | |
| 105 } | |
| 106 // WS-SecurityPolicy Elements | |
| 107 sp__Elements *elts = NULL; | |
| 108 const char *elts_name = NULL; | |
| 109 if (sp__SignedElements) | |
| 110 { elts = sp__SignedElements; | |
| 111 elts_name = "[4.1.2] Signed"; | |
| 112 } | |
| 113 if (sp__EncryptedElements) | |
| 114 { elts = sp__EncryptedElements; | |
| 115 elts_name = "[4.2.2] Encrypted"; | |
| 116 } | |
| 117 if (sp__ContentEncryptedElements) | |
| 118 { elts = sp__ContentEncryptedElements; | |
| 119 elts_name = "[4.2.3] Content Encrypted"; | |
| 120 } | |
| 121 if (sp__RequiredElements) | |
| 122 { elts = sp__RequiredElements; | |
| 123 elts_name = "[4.3.1] Required"; | |
| 124 } | |
| 125 if (elts) | |
| 126 { fprintf(stream, "%s- %s Elements requirements (XPath%s):\n%s @verbatim\n", tabs, elts_name, elts->XPathVersion?elts->XPathVersion:"", tabs); | |
| 127 for (vector<xsd__string>::const_iterator s = elts->XPath.begin(); s != elts->XPath.end(); ++s) | |
| 128 { fprintf(stream, "%s ", tabs); | |
| 129 text(*s); | |
| 130 } | |
| 131 fprintf(stream, "%s @endverbatim\n", tabs); | |
| 132 service.add_import("wsse.h"); | |
| 133 } | |
| 134 // WS-SecurityPolicy Tokens | |
| 135 sp__Token *token = NULL; | |
| 136 const char *token_name = NULL; | |
| 137 if (sp__UsernameToken) | |
| 138 { token = sp__UsernameToken; | |
| 139 token_name = "[5.4.1] WS-Security Username"; | |
| 140 } | |
| 141 else if (sp__IssuedToken) | |
| 142 { token = sp__IssuedToken; | |
| 143 token_name = "[5.4.2] WS-Trust Issued"; | |
| 144 } | |
| 145 else if (sp__X509Token) | |
| 146 { token = sp__X509Token; | |
| 147 token_name = "[5.4.3] WS-Security X509"; | |
| 148 } | |
| 149 else if (sp__KerberosToken) | |
| 150 { token = sp__KerberosToken; | |
| 151 token_name = "[5.4.4] WS-Security Kerberos"; | |
| 152 } | |
| 153 else if (sp__SpnegoContextToken) | |
| 154 { token = sp__SpnegoContextToken; | |
| 155 token_name = "[5.4.5] WS-Trust n-leg RST/RSTR SPNEGO binary negotiation protocol (SpnegoContext)"; | |
| 156 } | |
| 157 else if (sp__SecurityContextToken) | |
| 158 { token = sp__SecurityContextToken; | |
| 159 token_name = "[5.4.6] WS-SecureConversation SecurityContext"; | |
| 160 } | |
| 161 else if (sp__SecureConversationToken) | |
| 162 { token = sp__SecureConversationToken; | |
| 163 token_name = "[5.4.7] WS-SecureConversation"; | |
| 164 } | |
| 165 else if (sp__SamlToken) | |
| 166 { token = sp__SamlToken; | |
| 167 token_name = "[5.4.8] SAML"; | |
| 168 } | |
| 169 else if (sp__RelToken) | |
| 170 { token = sp__RelToken; | |
| 171 token_name = "[5.4.9] WSS-REL"; | |
| 172 } | |
| 173 else if (sp__HttpsToken) | |
| 174 { token = sp__HttpsToken; | |
| 175 token_name = "[5.4.10] HTTPS"; | |
| 176 } | |
| 177 else if (sp__KeyValueToken) | |
| 178 { token = sp__KeyValueToken; | |
| 179 token_name = "[5.4.11] XML Signature"; | |
| 180 } | |
| 181 if (token) | |
| 182 { fprintf(stream, "%s- %s required:\n", tabs, token_name); | |
| 183 if (token->IncludeToken) | |
| 184 fprintf(stream, "%s -# IncludeToken = %s\n", tabs, token->IncludeToken); | |
| 185 if (token->Issuer && token->Issuer->Address) | |
| 186 fprintf(stream, "%s -# Issuer = %s\n", tabs, token->Issuer->Address); | |
| 187 if (token->IssuerName) | |
| 188 fprintf(stream, "%s -# Issuer Name = %s\n", tabs, token->IssuerName); | |
| 189 if (token->Policy) | |
| 190 token->Policy->generate(service, types, indent + 1); | |
| 191 // TODO: add wst:Claims? | |
| 192 service.add_import("wsse.h"); | |
| 193 } | |
| 194 // WS-SecurityPolicy | |
| 195 if (sp__AlgorithmSuite) | |
| 196 { fprintf(stream, "%s- [7.1] Security Binding Algorithm Suite requirements:\n", tabs); | |
| 197 if (sp__AlgorithmSuite->Policy) | |
| 198 sp__AlgorithmSuite->Policy->generate(service, types, indent + 1); | |
| 199 } | |
| 200 if (sp__Layout) | |
| 201 { fprintf(stream, "%s- [7.2] WS-Security Header Layout requirements:\n", tabs); | |
| 202 if (sp__Layout->Policy) | |
| 203 sp__Layout->Policy->generate(service, types, indent + 1); | |
| 204 } | |
| 205 if (sp__TransportBinding) | |
| 206 { fprintf(stream, "%s- [7.3] Transport Binding%s requirements:\n", tabs, sp__TransportBinding->Optional ? " (optional)" : sp__TransportBinding->Ignorable ? " (ignorable)" : ""); | |
| 207 if (sp__TransportBinding->Policy) | |
| 208 sp__TransportBinding->Policy->generate(service, types, indent + 1); | |
| 209 } | |
| 210 if (sp__TransportToken) | |
| 211 { fprintf(stream, "%s- Transport%s requirements:\n", tabs, sp__TransportToken->Optional ? " (optional)" : sp__TransportToken->Ignorable ? " (ignorable)" : ""); | |
| 212 if (sp__TransportToken->Policy) | |
| 213 sp__TransportToken->Policy->generate(service, types, indent + 1); | |
| 214 } | |
| 215 if (sp__SymmetricBinding) | |
| 216 { fprintf(stream, "%s- [7.4] WS-Security Symmetric Binding%s requirements:\n", tabs, sp__SymmetricBinding->Optional ? " (optional)" : sp__SymmetricBinding->Ignorable ? " (ignorable)" : ""); | |
| 217 if (sp__SymmetricBinding->Policy) | |
| 218 sp__SymmetricBinding->Policy->generate(service, types, indent + 1); | |
| 219 service.add_import("wsse.h"); | |
| 220 } | |
| 221 if (sp__ProtectionToken) | |
| 222 { fprintf(stream, "%s- Symmetric Protection%s requirements:\n", tabs, sp__ProtectionToken->Optional ? " (optional)" : sp__ProtectionToken->Ignorable ? " (ignorable)" : ""); | |
| 223 if (sp__ProtectionToken->Policy) | |
| 224 sp__ProtectionToken->Policy->generate(service, types, indent + 1); | |
| 225 } | |
| 226 if (sp__AsymmetricBinding) | |
| 227 { fprintf(stream, "%s- [7.5] WS-Security Asymmetric Binding%s (public key) requirements:\n", tabs, sp__AsymmetricBinding->Optional ? " (optional)" : sp__AsymmetricBinding->Ignorable ? " (ignorable)" : ""); | |
| 228 if (sp__AsymmetricBinding->Policy) | |
| 229 sp__AsymmetricBinding->Policy->generate(service, types, indent + 1); | |
| 230 service.add_import("wsse.h"); | |
| 231 } | |
| 232 if (sp__InitiatorToken) | |
| 233 { fprintf(stream, "%s- Initiator%s requirements:\n", tabs, sp__InitiatorToken->Optional ? " (optional)" : sp__InitiatorToken->Ignorable ? " (ignorable)" : ""); | |
| 234 if (sp__InitiatorToken->Policy) | |
| 235 sp__InitiatorToken->Policy->generate(service, types, indent + 1); | |
| 236 } | |
| 237 if (sp__InitiatorSignatureToken) | |
| 238 { fprintf(stream, "%s- Initiator Signature%s requirements:\n", tabs, sp__InitiatorSignatureToken->Optional ? " (optional)" : sp__InitiatorSignatureToken->Ignorable ? " (ignorable)" : ""); | |
| 239 if (sp__InitiatorSignatureToken->Policy) | |
| 240 sp__InitiatorSignatureToken->Policy->generate(service, types, indent + 1); | |
| 241 } | |
| 242 if (sp__InitiatorEncryptionToken) | |
| 243 { fprintf(stream, "%s- Initiator Encryption%s requirements:\n", tabs, sp__InitiatorEncryptionToken->Optional ? " (optional)" : sp__InitiatorEncryptionToken->Ignorable ? " (ignorable)" : ""); | |
| 244 if (sp__InitiatorEncryptionToken->Policy) | |
| 245 sp__InitiatorEncryptionToken->Policy->generate(service, types, indent + 1); | |
| 246 } | |
| 247 if (sp__RecipientToken) | |
| 248 { fprintf(stream, "%s- Recipient%s requirements:\n", tabs, sp__RecipientToken->Optional ? " (optional)" : sp__RecipientToken->Ignorable ? " (ignorable)" : ""); | |
| 249 if (sp__RecipientToken->Policy) | |
| 250 sp__RecipientToken->Policy->generate(service, types, indent + 1); | |
| 251 } | |
| 252 if (sp__SupportingTokens) | |
| 253 { fprintf(stream, "%s- [8.1] Supporting Tokens%s requirements:\n", tabs, sp__SupportingTokens->Optional ? " (optional)" : sp__SupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 254 if (sp__SupportingTokens->Policy) | |
| 255 sp__SupportingTokens->Policy->generate(service, types, indent + 1); | |
| 256 } | |
| 257 if (sp__SignedSupportingTokens) | |
| 258 { fprintf(stream, "%s- [8.2] Signed Supporting Tokens%s requirements:\n", tabs, sp__SignedSupportingTokens->Optional ? " (optional)" : sp__SignedSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 259 if (sp__SignedSupportingTokens->Policy) | |
| 260 sp__SignedSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 261 } | |
| 262 if (sp__EndorsingSupportingTokens) | |
| 263 { fprintf(stream, "%s- [8.3] Endorsing Supporting Tokens%s requirements:\n", tabs, sp__EndorsingSupportingTokens->Optional ? " (optional)" : sp__EndorsingSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 264 if (sp__EndorsingSupportingTokens->Policy) | |
| 265 sp__EndorsingSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 266 } | |
| 267 if (sp__SignedEndorsingSupportingTokens) | |
| 268 { fprintf(stream, "%s- [8.4] Signed Endorsing Supporting Tokens%s requirements:\n", tabs, sp__SignedEndorsingSupportingTokens->Optional ? " (optional)" : sp__SignedEndorsingSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 269 if (sp__SignedEndorsingSupportingTokens->Policy) | |
| 270 sp__SignedEndorsingSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 271 } | |
| 272 if (sp__SignedEncryptedSupportingTokens) | |
| 273 { fprintf(stream, "%s- [8.5] Signed Encrypted Supporting Tokens%s requirements:\n", tabs, sp__SignedEncryptedSupportingTokens->Optional ? " (optional)" : sp__SignedEncryptedSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 274 if (sp__SignedEncryptedSupportingTokens->Policy) | |
| 275 sp__SignedEncryptedSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 276 } | |
| 277 if (sp__EncryptedSupportingTokens) | |
| 278 { fprintf(stream, "%s- [8.6] Encrypted Supporting Tokens%s requirements:\n", tabs, sp__EncryptedSupportingTokens->Optional ? " (optional)" : sp__EncryptedSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 279 if (sp__EncryptedSupportingTokens->Policy) | |
| 280 sp__EncryptedSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 281 } | |
| 282 if (sp__EndorsingEncryptedSupportingTokens) | |
| 283 { fprintf(stream, "%s- [8.7] Endorsing Encrypted Supporting Tokens%s requirements:\n", tabs, sp__EndorsingEncryptedSupportingTokens->Optional ? " (optional)" : sp__EndorsingEncryptedSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 284 if (sp__EndorsingEncryptedSupportingTokens->Policy) | |
| 285 sp__EndorsingEncryptedSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 286 } | |
| 287 if (sp__SignedEndorsingEncryptedSupportingTokens) | |
| 288 { fprintf(stream, "%s- [8.8] Signed Endorsing Encrypted Supporting Tokens%s requirements:\n", tabs, sp__SignedEndorsingEncryptedSupportingTokens->Optional ? " (optional)" : sp__SignedEndorsingEncryptedSupportingTokens->Ignorable ? " (ignorable)" : ""); | |
| 289 if (sp__SignedEndorsingEncryptedSupportingTokens->Policy) | |
| 290 sp__SignedEndorsingEncryptedSupportingTokens->Policy->generate(service, types, indent + 1); | |
| 291 } | |
| 292 // Wss10 or Wss11 | |
| 293 if (sp__Wss10) | |
| 294 { fprintf(stream, "%s- [9.1] WSS: SOAP Message Security 1.0%s options:\n", tabs, sp__Wss10->Optional ? " (optional)" : sp__Wss10->Ignorable ? " (ignorable)" : ""); | |
| 295 if (sp__Wss10->Policy) | |
| 296 sp__Wss10->Policy->generate(service, types, indent + 1); | |
| 297 service.add_import("wsse.h"); | |
| 298 } | |
| 299 else if (sp__Wss11) | |
| 300 { fprintf(stream, "%s- [9.2] WSS: SOAP Message Security 1.1%s options:\n", tabs, sp__Wss11->Optional ? " (optional)" : sp__Wss11->Ignorable ? " (ignorable)" : ""); | |
| 301 if (sp__Wss11->Policy) | |
| 302 sp__Wss11->Policy->generate(service, types, indent + 1); | |
| 303 service.add_import("wsse.h"); | |
| 304 } | |
| 305 if (sp__MustSupportRefKeyIdentifier) | |
| 306 fprintf(stream, "%s- Key Identifier References\n", tabs); | |
| 307 if (sp__MustSupportRefIssuerSerial) | |
| 308 fprintf(stream, "%s- Issuer Serial References\n", tabs); | |
| 309 if (sp__MustSupportRefExternalURI) | |
| 310 fprintf(stream, "%s- External URI References\n", tabs); | |
| 311 if (sp__MustSupportRefEmbeddedToken) | |
| 312 fprintf(stream, "%s- Embedded Token References\n", tabs); | |
| 313 if (sp__MustSupportRefThumbprint) | |
| 314 fprintf(stream, "%s- Thumbprint References\n", tabs); | |
| 315 if (sp__MustSupportRefEncryptedKey) | |
| 316 fprintf(stream, "%s- EncryptedKey References\n", tabs); | |
| 317 if (sp__RequireSignatureConfirmation) | |
| 318 fprintf(stream, "%s- Signature Confirmation\n", tabs); | |
| 319 // WS-SecureConversation | |
| 320 if (sp__RequireDerivedKeys) | |
| 321 fprintf(stream, "%s- Properties = WS-SecureConversation RequireDerivedKeys\n", tabs); | |
| 322 else if (sp__RequireImpliedDerivedKeys) | |
| 323 fprintf(stream, "%s- Properties = WS-SecureConversation RequireImpliedDerivedKeys\n", tabs); | |
| 324 else if (sp__RequireExplicitDerivedKeys) | |
| 325 fprintf(stream, "%s- Properties = WS-SecureConversation RequireExplicitDerivedKeys\n", tabs); | |
| 326 if (sp__MustNotSendCancel) | |
| 327 fprintf(stream, "%s- WS-SecureConversation STS issuing the secure conversation token does not support SCT/Cancel RST messages", tabs); | |
| 328 else if (sp__MustNotSendAmend) | |
| 329 fprintf(stream, "%s- WS-SecureConversation STS issuing the secure conversation token does not support SCT/Amend RST messages", tabs); | |
| 330 else if (sp__MustNotSendRenew) | |
| 331 fprintf(stream, "%s- WS-SecureConversation STS issuing the secure conversation token does not support SCT/Renew RST messages", tabs); | |
| 332 if (sp__RequireExternalUriReference) | |
| 333 fprintf(stream, "%s- WS-SecureConversation external URI reference is required", tabs); | |
| 334 if (sp__SC13SecurityContextToken) | |
| 335 fprintf(stream, "%s- WS-SecureConversation Security Context Token should be used", tabs); | |
| 336 // WS-Security passwords | |
| 337 if (sp__NoPassword) | |
| 338 fprintf(stream, "%s- No WS-Security password%s required\n", tabs, sp__NoPassword->Optional ? " (optional)" : sp__NoPassword->Ignorable ? " (ignorable)" : ""); | |
| 339 else if (sp__HashPassword) | |
| 340 { fprintf(stream, "%s- Client-side WS-Security password%s should be set:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_UsernameTokenDigest(soap, \"User\", \"<username>\", \"<password>\");\n\t@endcode\n", tabs, sp__HashPassword->Optional ? " (optional)" : sp__HashPassword->Ignorable ? " (ignorable)" : ""); | |
| 341 fprintf(stream, "%s- Server-side WS-Security password%s verified with:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tconst char *username = soap_wsse_get_Username(soap);\n\t...\n\tif (soap_wsse_verify_Password(soap, \"<password>\")) ...<error>...\n\t@endcode\n", tabs, sp__HashPassword->Optional ? " (optional)" : sp__HashPassword->Ignorable ? " (ignorable)" : ""); | |
| 342 service.add_import("wsse.h"); | |
| 343 } | |
| 344 if (sp__WssUsernameToken10) | |
| 345 { fprintf(stream, "%s- Username token should be used as defined in UsernameTokenProfile1.0:\n", tabs); | |
| 346 fprintf(stream, "%s - Client-side WS-Security password should be set:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_UsernameTokenDigest(soap, \"User\", \"<username>\", \"<password>\");\n\t@endcode\n", tabs); | |
| 347 fprintf(stream, "%s - Server-side WS-Security password verified with:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tconst char *username = soap_wsse_get_Username(soap);\n\t...\n\tif (soap_wsse_verify_Password(soap, \"<password>\")) <error>\n\t@endcode\n", tabs); | |
| 348 service.add_import("wsse.h"); | |
| 349 } | |
| 350 else if (sp__WssUsernameToken11) | |
| 351 { fprintf(stream, "%s- Username token should be used as defined in UsernameTokenProfile1.1:\n", tabs); | |
| 352 fprintf(stream, "%s - Client-side WS-Security plain-text password should be set:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_UsernameToken(soap, \"User\", \"<username>\", \"<password>\");\n\t@endcode\n", tabs); | |
| 353 fprintf(stream, "%s - Client-side WS-Security digest password should be set:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_UsernameTokenDigest(soap, \"User\", \"<username>\", \"<password>\");\n\t@endcode\n", tabs); | |
| 354 fprintf(stream, "%s - Server-side WS-Security password verified with:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tconst char *username = soap_wsse_get_Username(soap);\n\t...\n\tif (soap_wsse_verify_Password(soap, \"<password>\")) ...\n\t@endcode\n", tabs); | |
| 355 service.add_import("wsse.h"); | |
| 356 } | |
| 357 // WS-Trust | |
| 358 if (sp__RequireExternalReference) | |
| 359 fprintf(stream, "%s- WS-Trust external reference is required when referencing this token\n", tabs); | |
| 360 else if (sp__RequireInternalReference) | |
| 361 fprintf(stream, "%s- WS-Trust internal reference is required when referencing this token\n", tabs); | |
| 362 // WS-Trust 1.0 and 1.3 | |
| 363 if (sp__Trust10) | |
| 364 { fprintf(stream, "%s- [10.1] WS-Trust 1.0%s options:\n", tabs, sp__Trust10->Optional ? " (optional)" : sp__Trust10->Ignorable ? " (ignorable)" : ""); | |
| 365 if (sp__Trust10->Policy) | |
| 366 sp__Trust10->Policy->generate(service, types, indent + 1); | |
| 367 service.add_import("wst.h"); | |
| 368 } | |
| 369 else if (sp__Trust13) | |
| 370 { fprintf(stream, "%s- [10.1] WS-Trust 1.3%s options:\n", tabs, sp__Trust13->Optional ? " (optional)" : sp__Trust13->Ignorable ? " (ignorable)" : ""); | |
| 371 if (sp__Trust13->Policy) | |
| 372 sp__Trust13->Policy->generate(service, types, indent + 1); | |
| 373 service.add_import("wst.h"); | |
| 374 } | |
| 375 if (sp__MustSupportClientChallenge) | |
| 376 { fprintf(stream, "%s- Client Challenge\n", tabs); | |
| 377 service.add_import("wst.h"); | |
| 378 } | |
| 379 if (sp__MustSupportServerChallenge) | |
| 380 { fprintf(stream, "%s- Server Challenge\n", tabs); | |
| 381 service.add_import("wst.h"); | |
| 382 } | |
| 383 if (sp__RequireClientEntropy) | |
| 384 { fprintf(stream, "%s- Client Entropy\n", tabs); | |
| 385 service.add_import("wst.h"); | |
| 386 } | |
| 387 if (sp__RequireServerEntropy) | |
| 388 { fprintf(stream, "%s- Server Entropy\n", tabs); | |
| 389 service.add_import("wst.h"); | |
| 390 } | |
| 391 if (sp__MustSupportIssuedTokens) | |
| 392 { fprintf(stream, "%s- Issued Tokens\n", tabs); | |
| 393 service.add_import("wst.h"); | |
| 394 } | |
| 395 if (sp__RequireRequestSecurityTokenCollection) | |
| 396 { fprintf(stream, "%s- Collection\n", tabs); | |
| 397 service.add_import("wst.h"); | |
| 398 } | |
| 399 if (sp__RequireAppliesTo) | |
| 400 { fprintf(stream, "%s- STS requires the requestor to specify the scope for the issued token using wsp:AppliesTo in the RST\n", tabs); | |
| 401 service.add_import("wst.h"); | |
| 402 } | |
| 403 // WS-Security header layout | |
| 404 if (sp__IncludeTimestamp) | |
| 405 { fprintf(stream, "%s- WS-Security Timestamp%s should be set prior to send:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_Timestamp(soap, \"Timestamp\", <seconds>);\n\t@endcode\n", tabs, sp__IncludeTimestamp->Optional ? " (optional)" : sp__IncludeTimestamp->Ignorable ? " (ignorable)" : ""); | |
| 406 fprintf(stream, "%s- WS-Security Timestamp%s presence and expiration verified post-receive with:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tif (soap_wsse_verify_Timestamp(soap)) ...<error>...\n\t@endcode\n", tabs, sp__IncludeTimestamp->Optional ? " (optional)" : sp__IncludeTimestamp->Ignorable ? " (ignorable)" : ""); | |
| 407 } | |
| 408 if (sp__EncryptBeforeSigning) | |
| 409 fprintf(stream, "%s- WS-Security Encrypt Before Signing%s (gSOAP unsupported)\n", tabs, sp__EncryptBeforeSigning->Optional ? " (optional)" : sp__EncryptBeforeSigning->Ignorable ? " (ignorable)" : ""); | |
| 410 if (sp__EncryptSignature) | |
| 411 fprintf(stream, "%s- WS-Security Encrypt Signature%s\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_add_EncryptedKey_encrypt_only(soap, <SOAP_MEC_ENV_ENC_xxx_CBC>, NULL, <cert>, NULL, <issuer>, <serial>, \"ds:Signature SOAP-ENV:Body\");\n\t@endcode\n", tabs, sp__EncryptSignature->Optional ? " (optional)" : sp__EncryptSignature->Ignorable ? " (ignorable)" : ""); | |
| 412 if (sp__ProtectTokens) | |
| 413 fprintf(stream, "%s- WS-Security Token Protection%s required\n", tabs, sp__ProtectTokens->Optional ? " (optional)" : sp__ProtectTokens->Ignorable ? " (ignorable)" : ""); | |
| 414 if (sp__OnlySignEntireHeadersAndBody) | |
| 415 { fprintf(stream, "%s- WS-Security Sign Entire Headers and Body%s:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_set_wsu_id(soap, \"<ns:tagname1> <ns:tagname2> ...\"); // list each ns:tagname used in SOAP Header\n\tsoap_wsse_sign_body(soap, <algorithm>, <key>, <keylen>);\n\t@endcode\n", tabs, sp__OnlySignEntireHeadersAndBody->Optional ? " (optional)" : sp__OnlySignEntireHeadersAndBody->Ignorable ? " (ignorable)" : ""); | |
| 416 } | |
| 417 if (sp__Strict) | |
| 418 fprintf(stream, "%s- WS-Security headers 'declare before use' required (gSOAP default)\n", tabs); | |
| 419 else if (sp__Lax) | |
| 420 fprintf(stream, "%s- WS-Security headers may occur in any order (gSOAP allows this)\n", tabs); | |
| 421 else if (sp__LaxTsFirst) | |
| 422 fprintf(stream, "%s- WS-Security Timestamp must appear first (gSOAP default)\n", tabs); | |
| 423 else if (sp__LaxTsLast) | |
| 424 fprintf(stream, "%s- WS-Security Timestamp must appear last (requires changing the placement of the Timestamp header in SOAP_ENV__Header defined in import/wsse.h)\n", tabs); | |
| 425 // HTTP authentication | |
| 426 if (sp__HttpBasicAuthentication) | |
| 427 fprintf(stream, "%s- HTTP/S Basic Authentication required:\n\t@code\n\tsoap->userid = \"<userid>\"; soap->passwd = \"<passwd>\";\nsoap_call_ns__method(...)\n\t@endcode\n", tabs); | |
| 428 else if (sp__HttpDigestAuthentication) | |
| 429 fprintf(stream, "%s- HTTP/S Digest Authentication required:\n%sSee plugin/httpda.c plugin for usage details\n", tabs, tabs); | |
| 430 if (sp__RequireClientCertificate) | |
| 431 fprintf(stream, "%s- HTTPS client must authenticate to server with a certificate:\n\t@code\n\tsoap_ssl_client_context(soap, <sslflags>, \"<certkeyfile>\", \"<certkeypw>\", ...)\n\t@endcode\n", tabs); | |
| 432 // Security token requirements | |
| 433 if (sp__RequireKeyIdentifierReference) | |
| 434 fprintf(stream, "%s- Key identifier reference is required\n", tabs); | |
| 435 if (sp__RequireIssuerSerialReference) | |
| 436 fprintf(stream, "%s- Issuer serial reference is required\n", tabs); | |
| 437 if (sp__RequireEmbeddedTokenReference) | |
| 438 fprintf(stream, "%s- An embedded token reference is required\n", tabs); | |
| 439 if (sp__RequireThumbprintReference) | |
| 440 fprintf(stream, "%s- A thumbprint reference is required\n", tabs); | |
| 441 // Algorithm suite | |
| 442 if (sp__Basic256) | |
| 443 fprintf(stream, "%s- Basic256\n", tabs); | |
| 444 else if (sp__Basic192) | |
| 445 fprintf(stream, "%s- Basic192\n", tabs); | |
| 446 else if (sp__Basic128) | |
| 447 fprintf(stream, "%s- Basic128\n", tabs); | |
| 448 else if (sp__TripleDes) | |
| 449 fprintf(stream, "%s- TripleDes\n", tabs); | |
| 450 else if (sp__Basic256Rsa15) | |
| 451 fprintf(stream, "%s- Basic256Rsa15\n", tabs); | |
| 452 else if (sp__Basic192Rsa15) | |
| 453 fprintf(stream, "%s- Basic192Rsa15\n", tabs); | |
| 454 else if (sp__Basic128Rsa15) | |
| 455 fprintf(stream, "%s- Basic128Rsa15\n", tabs); | |
| 456 else if (sp__TripleDesRsa15) | |
| 457 fprintf(stream, "%s- TripleDesRsa15\n", tabs); | |
| 458 else if (sp__Basic256Sha256) | |
| 459 fprintf(stream, "%s- Basic256Sha256\n", tabs); | |
| 460 else if (sp__Basic192Sha256) | |
| 461 fprintf(stream, "%s- Basic192Sha256\n", tabs); | |
| 462 else if (sp__Basic128Sha256) | |
| 463 fprintf(stream, "%s- Basic128Sha256\n", tabs); | |
| 464 else if (sp__TripleDesSha256) | |
| 465 fprintf(stream, "%s- TripleDesSha256\n", tabs); | |
| 466 else if (sp__Basic256Sha256Rsa15) | |
| 467 fprintf(stream, "%s- Basic256Sha256Rsa15\n", tabs); | |
| 468 else if (sp__Basic192Sha256Rsa15) | |
| 469 fprintf(stream, "%s- Basic192Sha256Rsa15\n", tabs); | |
| 470 else if (sp__Basic128Sha256Rsa15) | |
| 471 fprintf(stream, "%s- Basic128Sha256Rsa15\n", tabs); | |
| 472 else if (sp__TripleDesSha256Rsa15) | |
| 473 fprintf(stream, "%s- TripleDesSha256Rsa15\n", tabs); | |
| 474 if (sp__InclusiveC14N) | |
| 475 fprintf(stream, "%s- InclusiveC14N\n", tabs); | |
| 476 if (sp__SOAPNormalization10) | |
| 477 fprintf(stream, "%s- SOAPNormalization10\n", tabs); | |
| 478 if (sp__STRTransform10) | |
| 479 fprintf(stream, "%s- STRTransform10\n", tabs); | |
| 480 if (sp__Path10) | |
| 481 fprintf(stream, "%s- Path10\n", tabs); | |
| 482 else if (sp__XPathFilter20) | |
| 483 fprintf(stream, "%s- XPathFilter20\n", tabs); | |
| 484 else if (sp__AbsXPath) | |
| 485 fprintf(stream, "%s- AbsXPath\n", tabs); | |
| 486 // WSS | |
| 487 if (sp__WssX509V3Token10) | |
| 488 fprintf(stream, "%s- An X509 Version 3 token should be used as defined in X509TokenProfile1.0\n", tabs); | |
| 489 else if (sp__WssX509Pkcs7Token10) | |
| 490 fprintf(stream, "%s- An X509 PKCS7 token should be used as defined in X509TokenProfile1.0\n", tabs); | |
| 491 else if (sp__WssX509PkiPathV1Token10) | |
| 492 fprintf(stream, "%s- An X509 PKI Path Version 1 token should be used as defined in X509TokenProfile1.0\n", tabs); | |
| 493 else if (sp__WssX509V1Token11) | |
| 494 fprintf(stream, "%s- An X509 Version 1 token should be used as defined in X509TokenProfile1.1\n", tabs); | |
| 495 else if (sp__WssX509V3Token11) | |
| 496 fprintf(stream, "%s- An X509 Version 3 token should be used as defined in X509TokenProfile1.1\n", tabs); | |
| 497 else if (sp__WssX509Pkcs7Token11) | |
| 498 fprintf(stream, "%s- An X509 PKCS7 token should be used as defined in X509TokenProfile1.1\n", tabs); | |
| 499 else if (sp__WssX509PkiPathV1Token11) | |
| 500 fprintf(stream, "%s- An X509 PKI Path Version 1 token should be used as defined in X509TokenProfile1.1\n", tabs); | |
| 501 if (sp__WssKerberosV5ApReqToken11) | |
| 502 fprintf(stream, "%s- A Kerberos Version 5 AP-REQ X509 token should be used as defined in KerberosTokenProfile1.1\n", tabs); | |
| 503 else if (sp__WssGssKerberosV5ApReqToken11) | |
| 504 fprintf(stream, "%s- A GSS Kerberos Version 5 AP-REQ token should be used as defined in KerberosTokenProfile1.1\n", tabs); | |
| 505 if (sp__WssRelV10Token10) | |
| 506 fprintf(stream, "%s- A REL Version 1.0 token should be used as defined in RELTokenProfile1.0\n", tabs); | |
| 507 else if (sp__WssRelV20Token10) | |
| 508 fprintf(stream, "%s- A REL Version 2.0 token should be used as defined in RELTokenProfile1.0\n", tabs); | |
| 509 else if (sp__WssRelV10Token11) | |
| 510 fprintf(stream, "%s- A REL Version 1.0 token should be used as defined in RELTokenProfile1.1\n", tabs); | |
| 511 else if (sp__WssRelV20Token11) | |
| 512 fprintf(stream, "%s- A REL Version 2.0 token should be used as defined in RELTokenProfile1.1\n", tabs); | |
| 513 if (sp__BootstrapPolicy) | |
| 514 { fprintf(stream, "%s- SecureConversation BootstrapPolicy\n", tabs); | |
| 515 sp__BootstrapPolicy->generate(service, types, indent + 1); | |
| 516 } | |
| 517 // WS-Addressing WSDL Policy | |
| 518 if (wsaw__UsingAddressing) | |
| 519 { fprintf(stream, "%s- WS-Addressing is used\n", tabs); | |
| 520 service.add_import("wsa5.h"); | |
| 521 } | |
| 522 // WS-Addressing Metadata Policy | |
| 523 if (wsam__Addressing) | |
| 524 { fprintf(stream, "%s- WS-Addressing%s is used\n", tabs, wsam__Addressing->Optional ? " (optional)" : wsam__Addressing->Ignorable ? " (ignorable)" : ""); | |
| 525 if (wsam__Addressing->Policy) | |
| 526 wsam__Addressing->Policy->generate(service, types, indent + 1); | |
| 527 service.add_import("wsa5.h"); | |
| 528 } | |
| 529 if (wsam__AnonymousResponses) | |
| 530 fprintf(stream, "%s- WS-Addressing Anonymous Responses\n", tabs); | |
| 531 else if (wsam__NonAnonymousResponses) | |
| 532 fprintf(stream, "%s- WS-Addressing NonAnonymous Responses\n", tabs); | |
| 533 // WS-ReliableMessaging Policy | |
| 534 if (wsrmp__RMAssertion_) | |
| 535 { fprintf(stream, "%s- WS-ReliableMessaging%s is used\n", tabs, wsrmp__RMAssertion_->Optional ? " (optional)" : wsrmp__RMAssertion_->Ignorable ? " (ignorable)" : ""); | |
| 536 if (wsrmp__RMAssertion_->InactivityTimeout && wsrmp__RMAssertion_->InactivityTimeout->Milliseconds) | |
| 537 fprintf(stream, "%s - Inactivity Timeout = %s (ms)\n", tabs, wsrmp__RMAssertion_->InactivityTimeout->Milliseconds); | |
| 538 if (wsrmp__RMAssertion_->BaseRetransmissionInterval && wsrmp__RMAssertion_->BaseRetransmissionInterval->Milliseconds) | |
| 539 fprintf(stream, "%s - Base Retransmission Interval = %s (ms)\n", tabs, wsrmp__RMAssertion_->BaseRetransmissionInterval->Milliseconds); | |
| 540 if (wsrmp__RMAssertion_->AcknowledgementInterval && wsrmp__RMAssertion_->AcknowledgementInterval->Milliseconds) | |
| 541 fprintf(stream, "%s - Acknowledgement Interval = %s (ms)\n", tabs, wsrmp__RMAssertion_->AcknowledgementInterval->Milliseconds); | |
| 542 if (wsrmp__RMAssertion_->ExponentialBackoff) | |
| 543 fprintf(stream, "%s - ExponentialBackoff\n", tabs); | |
| 544 if (wsrmp__RMAssertion_->Policy) | |
| 545 wsrmp__RMAssertion_->Policy->generate(service, types, indent + 1); | |
| 546 service.add_import("wsrm.h"); | |
| 547 } | |
| 548 if (wsrmp__DeliveryAssurance) | |
| 549 { fprintf(stream, "%s- WS-ReliableMessaging Delivery Assurance%s:\n", tabs, wsrmp__DeliveryAssurance->Optional ? " (optional)" : wsrmp__DeliveryAssurance->Ignorable ? " (ignorable)" : ""); | |
| 550 if (wsrmp__DeliveryAssurance->Policy) | |
| 551 wsrmp__DeliveryAssurance->Policy->generate(service, types, indent + 1); | |
| 552 service.add_import("wsrm.h"); | |
| 553 } | |
| 554 if (wsrmp__AtLeastOnce) | |
| 555 fprintf(stream, "%s- At Least Once\n", tabs); | |
| 556 if (wsrmp__AtMostOnce) | |
| 557 fprintf(stream, "%s- At Most Once\n", tabs); | |
| 558 if (wsrmp__ExactlyOnce) | |
| 559 fprintf(stream, "%s- Exactly Once\n", tabs); | |
| 560 if (wsrmp__InOrder) | |
| 561 fprintf(stream, "%s- In Order\n", tabs); | |
| 562 // All else | |
| 563 for (vector<_XML>::const_iterator x = __any.begin(); x != __any.end(); ++x) | |
| 564 { if (*x && *(*x)) | |
| 565 { fprintf(stream, "%s- Other policy requirements:\n\t@verbatim\n", tabs); | |
| 566 text(*x); | |
| 567 fprintf(stream, "\t@endverbatim\n"); | |
| 568 } | |
| 569 } | |
| 570 } | |
| 571 | |
| 572 static void gen_parts(const sp__Parts& parts, Types& types, const char *what, const char *name, int indent) | |
| 573 { static const char stabs[] = "\t\t\t\t\t\t\t\t\t\t"; | |
| 574 const char *tabs; | |
| 575 if (indent > 8) | |
| 576 indent = 8; | |
| 577 tabs = stabs + 9 - indent; | |
| 578 fprintf(stream, "%s- %s requirements:\n", tabs, name); | |
| 579 if (parts.Body) | |
| 580 fprintf(stream, "%s -# Body:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_%s_body(soap, <algorithm>, <key>, <keylen>);\n\t@endcode\n", tabs, what); | |
| 581 if (!parts.Header.empty()) | |
| 582 { fprintf(stream, "%s -# Header elements:\n\t@code\n\t#include \"plugin/wsseapi.h\"\n\tsoap_wsse_set_wsu_id(soap, \"", tabs); | |
| 583 for (vector<sp__Header>::const_iterator h = parts.Header.begin(); h != parts.Header.end(); ++h) | |
| 584 { if ((*h).Name) | |
| 585 fprintf(stream, "%s ", types.aname(NULL, (*h).Namespace, (*h).Name)); | |
| 586 else if ((*h).Namespace) | |
| 587 fprintf(stream, "%s: ", types.nsprefix(NULL, (*h).Namespace)); | |
| 588 } | |
| 589 fprintf(stream, "\");\n\t@endcode\n"); | |
| 590 } | |
| 591 if (parts.Attachments) | |
| 592 fprintf(stream, "%s -# Attachments as defined in SwAProfile1.1\n", tabs); | |
| 593 } | |
| 594 | |
| 595 //////////////////////////////////////////////////////////////////////////////// | |
| 596 // | |
| 597 // wsp:PolicyReference | |
| 598 // | |
| 599 //////////////////////////////////////////////////////////////////////////////// | |
| 600 | |
| 601 int wsp__PolicyReference::traverse(wsdl__definitions& definitions) | |
| 602 { policyRef = NULL; | |
| 603 if (!URI || !*URI) | |
| 604 { cerr << "PolicyReference has no URI" << endl; | |
| 605 return SOAP_OK; | |
| 606 } | |
| 607 if (*URI == '#') | |
| 608 { policyRef = search(URI + 1, definitions); | |
| 609 if (!policyRef) | |
| 610 { cerr << "PolicyReference URI=\"" << URI << "\" not found" << endl; | |
| 611 return SOAP_OK; | |
| 612 } | |
| 613 } | |
| 614 return SOAP_OK; | |
| 615 } | |
| 616 | |
| 617 void wsp__PolicyReference::policyPtr(wsp__Policy *Policy) | |
| 618 { policyRef = Policy; | |
| 619 } | |
| 620 | |
| 621 wsp__Policy *wsp__PolicyReference::policyPtr() const | |
| 622 { return policyRef; | |
| 623 } | |
| 624 | |
| 625 static wsp__Policy *search(const char *URI, wsdl__definitions& definitions) | |
| 626 { for (vector<wsp__Policy>::iterator p = definitions.wsp__Policy_.begin(); p != definitions.wsp__Policy_.end(); ++p) | |
| 627 { wsp__Policy *policy = search(URI, &(*p)); | |
| 628 if (policy) | |
| 629 return policy; | |
| 630 } | |
| 631 return NULL; | |
| 632 } | |
| 633 | |
| 634 static wsp__Policy *search(const char *URI, wsp__Policy *policy) | |
| 635 { if (!policy) | |
| 636 return NULL; | |
| 637 if (policy->wsu__Id && !strcmp(URI, policy->wsu__Id)) | |
| 638 return policy; | |
| 639 return search(URI, (wsp__Content*)policy); | |
| 640 } | |
| 641 | |
| 642 static wsp__Policy *search(const char *URI, wsp__Content *content) | |
| 643 { wsp__Policy *policy; | |
| 644 policy = search(URI, content->Policy); | |
| 645 if (policy) | |
| 646 return policy; | |
| 647 for (vector<wsp__Content*>::iterator i = content->All.begin(); i != content->All.end(); ++i) | |
| 648 { policy = search(URI, *i); | |
| 649 if (policy) | |
| 650 return policy; | |
| 651 } | |
| 652 for (vector<wsp__Content*>::iterator j = content->ExactlyOne.begin(); j != content->ExactlyOne.end(); ++j) | |
| 653 { policy = search(URI, *j); | |
| 654 if (policy) | |
| 655 return policy; | |
| 656 } | |
| 657 return NULL; | |
| 658 } |
