1 /*
2 * Copyright 2004,2005 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.apache.rahas.client;
18
19 import org.apache.axiom.om.OMElement;
20 import org.apache.axiom.om.OMNode;
21 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
22 import org.apache.axiom.om.impl.dom.DOOMAbstractFactory;
23 import org.apache.axiom.om.util.Base64;
24 import org.apache.axiom.soap.SOAP12Constants;
25 import org.apache.axis2.AxisFault;
26 import org.apache.axis2.addressing.AddressingConstants;
27 import org.apache.axis2.addressing.EndpointReference;
28 import org.apache.axis2.client.Options;
29 import org.apache.axis2.client.ServiceClient;
30 import org.apache.axis2.context.ConfigurationContext;
31 import org.apache.axis2.description.AxisOperation;
32 import org.apache.axis2.description.AxisService;
33 import org.apache.axis2.description.OutInAxisOperation;
34 import org.apache.axiom.om.util.UUIDGenerator;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.apache.neethi.Assertion;
38 import org.apache.neethi.Policy;
39 import org.apache.rahas.RahasConstants;
40 import org.apache.rahas.Token;
41 import org.apache.rahas.TokenStorage;
42 import org.apache.rahas.TrustException;
43 import org.apache.rahas.TrustUtil;
44 import org.apache.ws.secpolicy.model.AlgorithmSuite;
45 import org.apache.ws.secpolicy.model.Binding;
46 import org.apache.ws.secpolicy.model.Trust10;
47 import org.apache.ws.security.WSConstants;
48 import org.apache.ws.security.WSPasswordCallback;
49 import org.apache.ws.security.WSSecurityException;
50 import org.apache.ws.security.components.crypto.Crypto;
51 import org.apache.ws.security.conversation.ConversationException;
52 import org.apache.ws.security.conversation.dkalgo.P_SHA1;
53 import org.apache.ws.security.message.token.Reference;
54 import org.apache.ws.security.message.token.SecurityTokenReference;
55 import org.apache.ws.security.processor.EncryptedKeyProcessor;
56 import org.apache.ws.security.util.WSSecurityUtil;
57 import org.w3c.dom.Element;
58
59 import javax.security.auth.callback.Callback;
60 import javax.security.auth.callback.CallbackHandler;
61 import javax.security.auth.callback.UnsupportedCallbackException;
62 import javax.xml.namespace.QName;
63
64 import java.io.IOException;
65 import java.util.Iterator;
66 import java.util.List;
67 import java.util.Vector;
68
69 public class STSClient {
70
71 private static final String RAMPART_POLICY = "rampartPolicy";
72
73 private static Log log = LogFactory.getLog(STSClient.class);
74
75 private String action;
76
77 private OMElement rstTemplate;
78
79 private int version = RahasConstants.VERSION_05_02;
80
81 private Options options;
82
83 private Trust10 trust10;
84
85 private AlgorithmSuite algorithmSuite;
86
87 private byte[] requestorEntropy;
88
89 private String addressingNs = AddressingConstants.Submission.WSA_NAMESPACE;
90
91 private int keySize;
92
93 private String soapVersion = SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI;
94
95 /**
96 * Life time in seconds
97 * Default is 300 seconds (5 mins)
98 */
99 private int ttl = 300;
100 private Crypto crypto;
101 private CallbackHandler cbHandler;
102 private ConfigurationContext configCtx;
103
104 public STSClient(ConfigurationContext configCtx) throws TrustException {
105 if (configCtx != null) {
106 this.configCtx = configCtx;
107 } else {
108 throw new TrustException("stsClientCfgCtxNull");
109 }
110 }
111
112 public Token requestSecurityToken(Policy servicePolicy,
113 String issuerAddress,
114 Policy issuerPolicy,
115 String appliesTo) throws TrustException {
116 try {
117 QName rstQn = new QName("requestSecurityToken");
118 String requestType =
119 TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_ISSUE;
120
121 ServiceClient client = getServiceClient(rstQn, issuerAddress);
122
123 client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);
124 client.getOptions().setSoapVersionURI(this.soapVersion);
125 if(this.addressingNs != null) {
126 client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);
127 }
128 client.engageModule("addressing");
129 client.engageModule("rampart");
130
131 //Process the STS and service policy policy
132 this.processPolicy(issuerPolicy, servicePolicy);
133
134 OMElement response = client.sendReceive(rstQn,
135 createIssueRequest(requestType, appliesTo));
136
137 return processIssueResponse(version, response, issuerAddress);
138 } catch (AxisFault e) {
139 e.printStackTrace();
140 log.error("errorInObtainingToken", e);
141 throw new TrustException("errorInObtainingToken", new String[]{issuerAddress});
142 }
143 }
144
145 /**
146 * Cancel a particular security token
147 *
148 * @param issuerAddress
149 * @param tokenId
150 * @return true is the Token was successfully canceled. False otherwise.
151 * @throws TrustException
152 */
153 public boolean cancelToken(String issuerAddress,
154 String tokenId,
155 String action) throws TrustException {
156 try {
157 QName rstQn = new QName("cancelSecurityToken");
158 ServiceClient client = getServiceClient(rstQn, issuerAddress);
159 if(action != null) {
160 client.getOptions().setAction(action);
161 }
162
163 return processCancelResponse(client.sendReceive(rstQn,
164 createCancelRequest(tokenId)));
165 } catch (AxisFault e) {
166 log.error("errorInCancelingToken", e);
167 throw new TrustException("errorInCancelingToken", e);
168 }
169 }
170
171 public boolean validateToken(String tokenId,
172 String issuerAddress,
173 Policy issuerPolicy) throws TrustException {
174 try {
175 QName rstQn = new QName("requestSecurityToken");
176 String requestType =
177 TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_VALIDATE;
178
179 ServiceClient client = getServiceClient(rstQn, issuerAddress);
180
181 client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);
182 client.getOptions().setSoapVersionURI(this.soapVersion);
183 if(this.addressingNs != null) {
184 client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);
185 }
186 client.engageModule("addressing");
187 client.engageModule("rampart");
188
189 this.processPolicy(issuerPolicy, null);
190
191 OMElement response = client.sendReceive(rstQn,
192 createValidateRequest(requestType,tokenId));
193
194 System.out.println(response.toString());
195
196 return true;
197
198
199 } catch (AxisFault e) {
200 log.error("errorInValidatingToken", e);
201 throw new TrustException("errorInValidatingToken", new String[]{issuerAddress});
202 }
203
204 }
205
206 public boolean renewToken(String tokenId,
207 String issuerAddress,
208 Policy issuerPolicy) throws TrustException {
209
210 try {
211 QName rstQn = new QName("requestSecurityToken");
212
213 ServiceClient client = getServiceClient(rstQn, issuerAddress);
214
215 client.getServiceContext().setProperty(RAMPART_POLICY, issuerPolicy);
216 client.getOptions().setSoapVersionURI(this.soapVersion);
217 if(this.addressingNs != null) {
218 client.getOptions().setProperty(AddressingConstants.WS_ADDRESSING_VERSION, this.addressingNs);
219 }
220 client.engageModule("addressing");
221 client.engageModule("rampart");
222
223 this.processPolicy(issuerPolicy, null);
224
225 String tokenType = RahasConstants.TOK_TYPE_SAML_10;
226
227 OMElement response = client.sendReceive(rstQn,
228 createRenewRequest(tokenType,tokenId));
229
230 return true;
231
232 } catch (AxisFault e) {
233 log.error("errorInRenewingToken", e);
234 throw new TrustException("errorInRenewingToken", new String[]{issuerAddress});
235 }
236
237 }
238
239 private ServiceClient getServiceClient(QName rstQn,
240 String issuerAddress) throws AxisFault {
241 AxisService axisService =
242 new AxisService("SecurityTokenService" + UUIDGenerator.getUUID());
243 axisService.setClientSide(true);
244 AxisOperation operation = new OutInAxisOperation(rstQn);
245 axisService.addOperation(operation);
246 ServiceClient client = new ServiceClient(this.configCtx, axisService);
247
248 if (this.options != null) {
249 client.setOptions(options);
250 }
251
252 //Set the action
253 client.getOptions().setAction(action);
254 client.getOptions().setTo(new EndpointReference(issuerAddress));
255 client.engageModule("rampart");
256 return client;
257 }
258
259 /**
260 * @param result
261 * @return Token
262 */
263 private Token processIssueResponse(int version, OMElement result,
264 String issuerAddress) throws TrustException {
265 OMElement rstr = result;
266 if (version == RahasConstants.VERSION_05_12) {
267 //The WS-SX result will be an RSTRC
268 rstr = result.getFirstElement();
269 }
270
271 String ns = TrustUtil.getWSTNamespace(version);
272
273 //Get the RequestedAttachedReference
274 OMElement reqAttElem = rstr.getFirstChildWithName(new QName(
275 ns, RahasConstants.IssuanceBindingLocalNames.REQUESTED_ATTACHED_REFERENCE));
276 OMElement reqAttRef = reqAttElem == null ? null : reqAttElem.getFirstElement();
277
278 //Get the RequestedUnattachedReference
279 OMElement reqUnattElem =
280 rstr.getFirstChildWithName(new QName(ns,
281 RahasConstants.IssuanceBindingLocalNames.
282 REQUESTED_UNATTACHED_REFERENCE));
283 OMElement reqUnattRef = reqUnattElem == null ? null : reqUnattElem.getFirstElement();
284
285 //Get the security token
286 OMElement reqSecTok =
287 rstr.getFirstChildWithName(new QName(ns,
288 RahasConstants.IssuanceBindingLocalNames.
289 REQUESTED_SECURITY_TOKEN));
290 if (reqSecTok == null) {
291 throw new TrustException("reqestedSecTokMissing");
292 }
293
294 OMElement tokenElem = reqSecTok.getFirstElement();
295
296 String id = this.findIdentifier(reqAttRef, reqUnattRef, tokenElem);
297
298 if (id == null) {
299 throw new TrustException("cannotObtainTokenIdentifier");
300 }
301
302 OMElement lifeTimeEle =
303 rstr.getFirstChildWithName(new QName(ns,
304 RahasConstants.IssuanceBindingLocalNames.
305 LIFETIME));
306
307 Token token = new Token(id, tokenElem, lifeTimeEle);
308 token.setIssuerAddress(issuerAddress);
309 token.setAttachedReference(reqAttRef);
310 token.setUnattachedReference(reqUnattRef);
311
312 //Handle proof token
313 OMElement rpt =
314 rstr.getFirstChildWithName(new QName(ns,
315 RahasConstants.LocalNames.
316 REQUESTED_PROOF_TOKEN));
317
318 byte[] secret = null;
319
320 if (rpt != null) {
321 OMElement child = rpt.getFirstElement();
322 if (child == null) {
323 throw new TrustException("invalidRPT");
324 }
325 if (child.getQName().equals(new QName(ns,
326 RahasConstants.LocalNames.
327 BINARY_SECRET))) {
328 //First check for the binary secret
329 String b64Secret = child.getText();
330 secret = Base64.decode(b64Secret);
331 } else if (child.getQName().equals(new QName(ns, WSConstants.ENC_KEY_LN))) {
332 try {
333 Element domChild = (Element) new StAXOMBuilder(
334 DOOMAbstractFactory.getOMFactory(), child
335 .getXMLStreamReader()).getDocumentElement();
336
337 EncryptedKeyProcessor processor = new EncryptedKeyProcessor();
338
339 processor.handleToken(domChild, null, this.crypto,
340 this.cbHandler, null, new Vector(),
341 null);
342
343 secret = processor.getDecryptedBytes();
344 } catch (WSSecurityException e) {
345 throw new TrustException("errorInProcessingEncryptedKey", e);
346 }
347 } else if (child.getQName().equals(new QName(ns,
348 RahasConstants.IssuanceBindingLocalNames.
349 COMPUTED_KEY))) {
350 //Handle the computed key
351
352 //Get service entropy
353 OMElement serviceEntrElem = rstr
354 .getFirstChildWithName(new QName(ns,
355 RahasConstants.IssuanceBindingLocalNames.
356 ENTROPY));
357
358 OMElement binSecElem = serviceEntrElem.getFirstElement();
359
360 if (binSecElem != null && binSecElem.getText() != null
361 && !"".equals(binSecElem.getText().trim())) {
362
363 byte[] serviceEntr = Base64.decode(binSecElem.getText());
364
365 //Right now we only use PSHA1 as the computed key algo
366 P_SHA1 p_sha1 = new P_SHA1();
367
368 int length = (this.keySize > 0) ? keySize
369 : this.algorithmSuite
370 .getMaximumSymmetricKeyLength();
371 try {
372 secret = p_sha1.createKey(this.requestorEntropy, serviceEntr, 0, length/8);
373 } catch (ConversationException e) {
374 throw new TrustException("keyDerivationError", e);
375 }
376 } else {
377 //Service entropy missing
378 throw new TrustException("serviceEntropyMissing");
379 }
380 }
381
382 } else {
383 if (this.requestorEntropy != null) {
384 //Use requester entropy as the key
385 secret = this.requestorEntropy;
386 }
387 }
388 token.setSecret(secret);
389 return token;
390 }
391
392 private boolean processCancelResponse(OMElement response) {
393 /*
394 <wst:RequestSecurityTokenResponse>
395 <wst:RequestedTokenCancelled/>
396 </wst:RequestSecurityTokenResponse>
397 */
398 return response.
399 getFirstChildWithName(new QName(RahasConstants.
400 CancelBindingLocalNames.REQUESTED_TOKEN_CANCELED)) != null;
401 }
402
403 /**
404 * Find the token identifier.
405 *
406 * @param reqAttRef
407 * @param reqUnattRef
408 * @param token
409 * @return id
410 */
411 private String findIdentifier(OMElement reqAttRef,
412 OMElement reqUnattRef,
413 OMElement token) {
414 String id;
415 if (reqAttRef != null) {
416 //First try the attached ref
417 id = this.getIdFromSTR(reqAttRef);
418 } else if (reqUnattRef != null) {
419 //then try the unattached ref
420 id = this.getIdFromSTR(reqUnattRef);
421 } else {
422 //Return wsu:Id of the token element
423 id = token.getAttributeValue(new QName(WSConstants.WSU_NS, "Id"));
424 }
425 return id;
426 }
427
428
429 /**
430 * Process the given STR to find the id it refers to
431 *
432 * @param refElem
433 * @return id
434 */
435 private String getIdFromSTR(OMElement refElem) {
436 //ASSUMPTION:SecurityTokenReference/KeyIdentifier
437 OMElement child = refElem.getFirstElement();
438 if(child == null) {
439 return null;
440 }
441
442 if (child.getQName().equals(new QName(WSConstants.SIG_NS, "KeyInfo")) ||
443 child.getQName().equals(new QName(WSConstants.WSSE_NS, "KeyIdentifier"))) {
444 return child.getText();
445 } else if(child.getQName().equals(Reference.TOKEN)) {
446 return child.getAttributeValue(new QName("URI"));
447 } else {
448 return null;
449 }
450
451 }
452
453 /**
454 * Process the goven service policy and extract the info required to create
455 * the RST.
456 *
457 * @param servicePolicy
458 */
459 private void processPolicy(Policy issuerPolicy, Policy servicePolicy) {
460 //Get the policy assertions
461 //Assumption: there's only one alternative
462
463 if (issuerPolicy != null) {
464 log.debug("Processing Issuer policy");
465
466 List issuerAssertions = (List) issuerPolicy.getAlternatives().next();
467
468 for (Iterator iter = issuerAssertions.iterator(); iter.hasNext();) {
469 Assertion tempAssertion = (Assertion) iter.next();
470 //find the AlgorithmSuite assertion
471 if (tempAssertion instanceof Binding) {
472
473 log.debug("Extracting algo suite from issuer " +
474 "policy binding");
475
476 this.algorithmSuite = ((Binding) tempAssertion)
477 .getAlgorithmSuite();
478 }
479 }
480 }
481
482 if (servicePolicy != null) {
483
484 log.debug("Processing service policy to find Trust10 assertion");
485
486 List assertions = (List) servicePolicy.getAlternatives().next();
487
488 for (Iterator iter = assertions.iterator(); iter.hasNext();) {
489 Assertion tempAssertion = (Assertion) iter.next();
490 //find the Trust10 assertion
491 if (tempAssertion instanceof Trust10) {
492 log.debug("Extracting Trust10 assertion from " +
493 "service policy");
494 this.trust10 = (Trust10) tempAssertion;
495 }
496 }
497 }
498 }
499
500 /**
501 * Create the RST request.
502 *
503 * @param requestType
504 * @param appliesTo
505 * @return OMElement
506 * @throws TrustException
507 */
508 private OMElement createIssueRequest(String requestType,
509 String appliesTo) throws TrustException {
510
511 log.debug("Creating request with request type: " + requestType +
512 " and applies to: " + appliesTo);
513
514 OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);
515
516 TrustUtil.createRequestTypeElement(this.version, rst, requestType);
517 if (appliesTo != null) {
518 TrustUtil.createAppliesToElement(rst, appliesTo, this.addressingNs);
519 }
520 TrustUtil.createLifetimeElement(this.version, rst, this.ttl * 1000);
521
522 //Copy over the elements from the template
523 if (this.rstTemplate != null) {
524
525 log.debug("Using RSTTemplate: " + this.rstTemplate.toString());
526
527 Iterator templateChildren = rstTemplate.getChildElements();
528 while (templateChildren.hasNext()) {
529 OMNode child = (OMNode) templateChildren.next();
530 rst.addChild(child);
531 //Look for the key size element
532 if (child instanceof OMElement
533 && ((OMElement) child).getQName().equals(
534 new QName(TrustUtil.getWSTNamespace(this.version),
535 RahasConstants.IssuanceBindingLocalNames.KEY_SIZE))) {
536 log.debug("Extracting key size from the RSTTemplate: ");
537 OMElement childElem = (OMElement) child;
538 this.keySize =
539 (childElem.getText() != null && !"".equals(childElem.getText())) ?
540 Integer.parseInt(childElem.getText()) :
541 -1;
542 log.debug("Key size from RSTTemplate: " + this.keySize);
543 }
544 }
545 }
546
547 try {
548 // Handle entropy
549 if (this.trust10 != null) {
550
551 log.debug("Processing Trust10 assertion");
552
553 if (this.trust10.isRequireClientEntropy()) {
554
555 log.debug("Requires client entropy");
556
557 // setup requestor entropy
558 OMElement ent = TrustUtil.createEntropyElement(this.version, rst);
559 OMElement binSec =
560 TrustUtil.createBinarySecretElement(this.version,
561 ent,
562 RahasConstants.BIN_SEC_TYPE_NONCE);
563 this.requestorEntropy =
564 WSSecurityUtil.generateNonce(this.algorithmSuite.
565 getMaximumSymmetricKeyLength()/8);
566 binSec.setText(Base64.encode(this.requestorEntropy));
567
568 log.debug("Clien entropy : "
569 + Base64.encode(this.requestorEntropy));
570
571 // Add the ComputedKey element
572 TrustUtil.createComputedKeyAlgorithm(this.version, rst,
573 RahasConstants.COMPUTED_KEY_PSHA1);
574
575 }
576 }
577 } catch (Exception e) {
578 throw new TrustException("errorSettingUpRequestorEntropy", e);
579 }
580
581
582 return rst;
583
584 }
585
586 private OMElement createValidateRequest(String requestType, String tokenId) throws TrustException {
587
588 log.debug("Creating request with request type: " + requestType);
589
590 OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);
591
592 TrustUtil.createRequestTypeElement(this.version, rst, requestType);
593
594 OMElement tokenTypeElem = TrustUtil.createTokenTypeElement(this.version, rst);
595
596 String tokenType =
597 TrustUtil.getWSTNamespace(version) + RahasConstants.TOK_TYPE_STATUS;
598
599 tokenTypeElem.setText(tokenType);
600
601 TokenStorage store = TrustUtil.getTokenStore(configCtx);
602
603 Token token = store.getToken(tokenId);
604
605 if ( token != null) {
606
607 OMElement str = token.getUnattachedReference();
608
609 if (str == null) {
610 str = token.getAttachedReference();
611 }
612
613 TrustUtil.createValidateTargetElement(this.version, rst,str);
614
615
616 } else {
617 throw new TrustException("noToken",new String[]{tokenId});
618 }
619
620 return rst;
621
622 }
623
624 private OMElement createRenewRequest(String tokenType, String tokenId) throws TrustException {
625
626 String requestType =
627 TrustUtil.getWSTNamespace(version) + RahasConstants.REQ_TYPE_RENEW;
628
629 log.debug("Creating request with request type: " + requestType);
630
631 OMElement rst = TrustUtil.createRequestSecurityTokenElement(version);
632
633 TrustUtil.createRequestTypeElement(this.version, rst, requestType);
634
635 OMElement tokenTypeElem = TrustUtil.createTokenTypeElement(version, rst);
636 tokenTypeElem.setText(tokenType);
637
638 TokenStorage store = TrustUtil.getTokenStore(configCtx);
639
640 Token token = store.getToken(tokenId);
641
642 if ( token != null) {
643
644 OMElement str = token.getUnattachedReference();
645
646 if (str == null) {
647 str = token.getAttachedReference();
648 }
649
650 TrustUtil.createRenewTargetElement(this.version, rst,str);
651
652
653 } else {
654 throw new TrustException("noToken",new String[]{tokenId});
655 }
656
657 return rst;
658
659
660 }
661
662 private OMElement createCancelRequest(String tokenId) throws TrustException {
663
664 return TrustUtil.createCancelRequest(tokenId, version);
665 }
666
667 /**
668 * Set this to set the entropy configurations.
669 * If this is provided in the given policy it will be overridden.
670 *
671 * @param trust10 The trust10 to set.
672 */
673 public void setTrust10(Trust10 trust10) {
674 this.trust10 = trust10;
675 }
676
677 /**
678 * This can be used in the case where the AlgorithmSuite is not specified in
679 * the given policy.
680 * If the AlgorithmSuite exists in a binding in the policy then the value
681 * set will be overridden.
682 *
683 * @param algorithmSuite The algorithmSuite to set.
684 */
685 public void setAlgorithmSuite(AlgorithmSuite algorithmSuite) {
686 this.algorithmSuite = algorithmSuite;
687 }
688
689 /**
690 * @param addressingNs The addressingNs to set.
691 */
692 public void setAddressingNs(String addressingNs) {
693 this.addressingNs = addressingNs;
694 }
695
696 /**
697 * @param ttl The ttl to set.
698 */
699 public void setTtl(int ttl) {
700 this.ttl = ttl;
701 }
702
703 /**
704 * Sets the crypto information required to process the RSTR.
705 *
706 * @param crypto Crypto information
707 * @param cbHandler Callback handler to provide the private key password to
708 * decrypt
709 */
710 public void setCryptoInfo(Crypto crypto, CallbackHandler cbHandler) {
711 this.crypto = crypto;
712 this.cbHandler = cbHandler;
713 }
714
715 /**
716 * Sets the crypto information required to process the RSTR.
717 *
718 * @param crypto The crypto information
719 * @param privKeyPasswd Private key password to decrypt
720 */
721 public void setCryptoInfo(Crypto crypto, String privKeyPasswd) {
722 this.crypto = crypto;
723 this.cbHandler = new CBHandler(privKeyPasswd);
724 }
725
726 /**
727 * @param action The action to set.
728 */
729 public void setAction(String action) {
730 this.action = action;
731 }
732
733 /**
734 * @param options The options to set.
735 */
736 public void setOptions(Options options) {
737 this.options = options;
738 }
739
740 /**
741 * @param rstTemplate The rstTemplate to set.
742 */
743 public void setRstTemplate(OMElement rstTemplate) {
744 this.rstTemplate = rstTemplate;
745 }
746
747 private class CBHandler implements CallbackHandler {
748
749 private String passwd;
750
751 private CBHandler(String passwd) {
752 this.passwd = passwd;
753 }
754
755 public void handle(Callback[] cb) throws IOException,
756 UnsupportedCallbackException {
757 ((WSPasswordCallback) cb[0]).setPassword(this.passwd);
758 }
759
760 }
761
762 /**
763 * @param version The version to set.
764 */
765 public void setVersion(int version) {
766 this.version = version;
767 }
768
769 public void setSoapVersion(String soapVersion) {
770 this.soapVersion = soapVersion;
771 }
772
773 }