ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
SAML2\SOAPClient Class Reference
+ Collaboration diagram for SAML2\SOAPClient:

Public Member Functions

 send (Message $msg, SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata=null)
 This function sends the SOAP message to the service location and returns SOAP response. More...
 

Static Public Member Functions

static validateSSL ($data, XMLSecurityKey $key)
 Validate a SOAP message against the certificate on the SSL connection. More...
 

Data Fields

const START_SOAP_ENVELOPE = '<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header/><soap-env:Body>'
 
const END_SOAP_ENVELOPE = '</soap-env:Body></soap-env:Envelope>'
 

Private Member Functions

 getSOAPFault ($soapMessage)
 

Static Private Member Functions

static addSSLValidator (Message $msg, $context)
 Add a signature validator based on a SSL context. More...
 

Detailed Description

Definition at line 16 of file SOAPClient.php.

Member Function Documentation

◆ addSSLValidator()

static SAML2\SOAPClient::addSSLValidator ( Message  $msg,
  $context 
)
staticprivate

Add a signature validator based on a SSL context.

Parameters
\SAML2\Message$msgThe message we should add a validator to.
resource$contextThe stream context.

Definition at line 163 of file SOAPClient.php.

References $context, $key, PHPMailer\PHPMailer\$options, and SAML2\Message\addValidator().

164  {
165  $options = stream_context_get_options($context);
166  if (!isset($options['ssl']['peer_certificate'])) {
167  return;
168  }
169 
170  //$out = '';
171  //openssl_x509_export($options['ssl']['peer_certificate'], $out);
172 
173  $key = openssl_pkey_get_public($options['ssl']['peer_certificate']);
174  if ($key === false) {
175  Utils::getContainer()->getLogger()->warning('Unable to get public key from peer certificate.');
176 
177  return;
178  }
179 
180  $keyInfo = openssl_pkey_get_details($key);
181  if ($keyInfo === false) {
182  Utils::getContainer()->getLogger()->warning('Unable to get key details from public key.');
183 
184  return;
185  }
186 
187  if (!isset($keyInfo['key'])) {
188  Utils::getContainer()->getLogger()->warning('Missing key in public key details.');
189 
190  return;
191  }
192 
193  $msg->addValidator(array('\SAML2\SOAPClient', 'validateSSL'), $keyInfo['key']);
194  }
$context
Definition: webdav.php:25
$key
Definition: croninfo.php:18
static getContainer()
Definition: Utils.php:752
+ Here is the call graph for this function:

◆ getSOAPFault()

SAML2\SOAPClient::getSOAPFault (   $soapMessage)
private

Definition at line 230 of file SOAPClient.php.

231  {
232  $soapFault = Utils::xpQuery($soapMessage->firstChild, '/soap-env:Envelope/soap-env:Body/soap-env:Fault');
233 
234  if (empty($soapFault)) {
235  /* No fault. */
236 
237  return null;
238  }
239  $soapFaultElement = $soapFault[0];
240  // There is a fault element but we haven't found out what the fault string is
241  $soapFaultString = "Unknown fault string found";
242  // find out the fault string
243  $faultStringElement = Utils::xpQuery($soapFaultElement, './soap-env:faultstring') ;
244  if (!empty($faultStringElement)) {
245  return $faultStringElement[0]->textContent;
246  }
247 
248  return $soapFaultString;
249  }
static xpQuery(\DOMNode $node, $query)
Do an XPath query on an XML node.
Definition: Utils.php:191

◆ send()

SAML2\SOAPClient::send ( Message  $msg,
SimpleSAML_Configuration  $srcMetadata,
SimpleSAML_Configuration  $dstMetadata = null 
)

This function sends the SOAP message to the service location and returns SOAP response.

Parameters
\SAML2\Message$msgThe request that should be sent.
\SimpleSAML_Configuration$srcMetadataThe metadata of the issuer of the message.
\SimpleSAML_Configuration$dstMetadataThe metadata of the destination of the message.
Returns
The response we received.
Exceptions

Definition at line 30 of file SOAPClient.php.

References $action, $context, $destination, $issuer, $key, PHPMailer\PHPMailer\$options, $request, $version, $x, SAML2\Message\getDestination(), SAML2\Message\getIssuer(), SimpleSAML_Configuration\getString(), SimpleSAML_Utilities\getTempDir(), SimpleSAML_Configuration\getValue(), SimpleSAML_Configuration\hasValue(), SimpleSAML_Utilities\loadPrivateKey(), SimpleSAML_Utilities\loadPublicKey(), SimpleSAML_Utilities\resolveCert(), SAML2\Message\toSignedXML(), and SimpleSAML_Utilities\writeFile().

31  {
32  $issuer = $msg->getIssuer();
33 
34  $ctxOpts = array(
35  'ssl' => array(
36  'capture_peer_cert' => true,
37  'allow_self_signed' => true
38  ),
39  );
40 
41  // Determine if we are going to do a MutualSSL connection between the IdP and SP - Shoaib
42  if ($srcMetadata->hasValue('saml.SOAPClient.certificate')) {
43  $cert = $srcMetadata->getValue('saml.SOAPClient.certificate');
44  if ($cert !== false) {
45  $ctxOpts['ssl']['local_cert'] = SimpleSAML_Utilities::resolveCert(
46  $srcMetadata->getString('saml.SOAPClient.certificate')
47  );
48  if ($srcMetadata->hasValue('saml.SOAPClient.privatekey_pass')) {
49  $ctxOpts['ssl']['passphrase'] = $srcMetadata->getString('saml.SOAPClient.privatekey_pass');
50  }
51  }
52  } else {
53  /* Use the SP certificate and privatekey if it is configured. */
54  $privateKey = SimpleSAML_Utilities::loadPrivateKey($srcMetadata);
55  $publicKey = SimpleSAML_Utilities::loadPublicKey($srcMetadata);
56  if ($privateKey !== null && $publicKey !== null && isset($publicKey['PEM'])) {
57  $keyCertData = $privateKey['PEM'] . $publicKey['PEM'];
58  $file = SimpleSAML_Utilities::getTempDir() . '/' . sha1($keyCertData) . '.pem';
59  if (!file_exists($file)) {
60  SimpleSAML_Utilities::writeFile($file, $keyCertData);
61  }
62  $ctxOpts['ssl']['local_cert'] = $file;
63  if (isset($privateKey['password'])) {
64  $ctxOpts['ssl']['passphrase'] = $privateKey['password'];
65  }
66  }
67  }
68 
69  // do peer certificate verification
70  if ($dstMetadata !== null) {
71  $peerPublicKeys = $dstMetadata->getPublicKeys('signing', true);
72  $certData = '';
73  foreach ($peerPublicKeys as $key) {
74  if ($key['type'] !== 'X509Certificate') {
75  continue;
76  }
77  $certData .= "-----BEGIN CERTIFICATE-----\n" .
78  chunk_split($key['X509Certificate'], 64) .
79  "-----END CERTIFICATE-----\n";
80  }
81  $peerCertFile = SimpleSAML_Utilities::getTempDir() . '/' . sha1($certData) . '.pem';
82  if (!file_exists($peerCertFile)) {
83  SimpleSAML_Utilities::writeFile($peerCertFile, $certData);
84  }
85  // create ssl context
86  $ctxOpts['ssl']['verify_peer'] = true;
87  $ctxOpts['ssl']['verify_depth'] = 1;
88  $ctxOpts['ssl']['cafile'] = $peerCertFile;
89  }
90 
91  if ($srcMetadata->hasValue('saml.SOAPClient.stream_context.ssl.peer_name')) {
92  $ctxOpts['ssl']['peer_name'] = $srcMetadata->getString('saml.SOAPClient.stream_context.ssl.peer_name');
93  }
94 
95  $context = stream_context_create($ctxOpts);
96  if ($context === null) {
97  throw new \Exception('Unable to create SSL stream context');
98  }
99 
100  $options = array(
101  'uri' => $issuer,
102  'location' => $msg->getDestination(),
103  'stream_context' => $context,
104  );
105 
106  if ($srcMetadata->hasValue('saml.SOAPClient.proxyhost')) {
107  $options['proxy_host'] = $srcMetadata->getValue('saml.SOAPClient.proxyhost');
108  }
109 
110  if ($srcMetadata->hasValue('saml.SOAPClient.proxyport')) {
111  $options['proxy_port'] = $srcMetadata->getValue('saml.SOAPClient.proxyport');
112  }
113 
114  $x = new \SoapClient(null, $options);
115 
116  // Add soap-envelopes
117  $request = $msg->toSignedXML();
118  $request = self::START_SOAP_ENVELOPE . $request->ownerDocument->saveXML($request) . self::END_SOAP_ENVELOPE;
119 
120  Utils::getContainer()->debugMessage($request, 'out');
121 
122  $action = 'http://www.oasis-open.org/committees/security';
123  $version = '1.1';
124  $destination = $msg->getDestination();
125 
126  /* Perform SOAP Request over HTTP */
127  $soapresponsexml = $x->__doRequest($request, $destination, $action, $version);
128  if ($soapresponsexml === null || $soapresponsexml === "") {
129  throw new \Exception('Empty SOAP response, check peer certificate.');
130  }
131 
132  Utils::getContainer()->debugMessage($soapresponsexml, 'in');
133 
134  // Convert to SAML2\Message (\DOMElement)
135  try {
136  $dom = DOMDocumentFactory::fromString($soapresponsexml);
137  } catch (RuntimeException $e) {
138  throw new \Exception('Not a SOAP response.', 0, $e);
139  }
140 
141  $soapfault = $this->getSOAPFault($dom);
142  if (isset($soapfault)) {
143  throw new \Exception($soapfault);
144  }
145  //Extract the message from the response
146  $samlresponse = Utils::xpQuery($dom->firstChild, '/soap-env:Envelope/soap-env:Body/*[1]');
147  $samlresponse = Message::fromXML($samlresponse[0]);
148 
149  /* Add validator to message which uses the SSL context. */
150  self::addSSLValidator($samlresponse, $context);
151 
152  Utils::getContainer()->getLogger()->debug("Valid ArtifactResponse received from IdP");
153 
154  return $samlresponse;
155  }
static resolveCert($path)
Definition: Utilities.php:457
$context
Definition: webdav.php:25
$action
foreach($paths as $path) $request
Definition: asyncclient.php:32
hasValue($name)
Check whether a key in the configuration exists or not.
$destination
getValue($name, $default=null)
Retrieve a configuration option set in config.php.
static writeFile($filename, $data, $mode=0600)
Definition: Utilities.php:602
static loadPublicKey(SimpleSAML_Configuration $metadata, $required=false, $prefix='')
Definition: Utilities.php:466
$version
Definition: build.php:27
static xpQuery(\DOMNode $node, $query)
Do an XPath query on an XML node.
Definition: Utils.php:191
catch(Exception $e) if(!($request instanceof \SAML2\ArtifactResolve)) $issuer
getPublicKeys($use=null, $required=false, $prefix='')
Get public key from metadata.
getString($name, $default=self::REQUIRED_OPTION)
This function retrieves a string configuration option.
static loadPrivateKey(SimpleSAML_Configuration $metadata, $required=false, $prefix='')
Definition: Utilities.php:475
static fromXML(\DOMElement $xml)
Convert an XML element into a message.
Definition: Message.php:562
$key
Definition: croninfo.php:18
$x
Definition: complexTest.php:9
getSOAPFault($soapMessage)
Definition: SOAPClient.php:230
static getContainer()
Definition: Utils.php:752
+ Here is the call graph for this function:

◆ validateSSL()

static SAML2\SOAPClient::validateSSL (   $data,
XMLSecurityKey  $key 
)
static

Validate a SOAP message against the certificate on the SSL connection.

Parameters
string$dataThe public key that was used on the connection.
XMLSecurityKey$keyThe key we should validate the certificate against.
Exceptions

Definition at line 203 of file SOAPClient.php.

References $data.

204  {
205  assert(is_string($data));
206 
207  $keyInfo = openssl_pkey_get_details($key->key);
208  if ($keyInfo === false) {
209  throw new \Exception('Unable to get key details from XMLSecurityKey.');
210  }
211 
212  if (!isset($keyInfo['key'])) {
213  throw new \Exception('Missing key in public key details.');
214  }
215 
216  if ($keyInfo['key'] !== $data) {
217  Utils::getContainer()->getLogger()->debug('Key on SSL connection did not match key we validated against.');
218 
219  return;
220  }
221 
222  Utils::getContainer()->getLogger()->debug('Message validated based on SSL certificate.');
223  }
$key
Definition: croninfo.php:18
$data
Definition: bench.php:6
static getContainer()
Definition: Utils.php:752

Field Documentation

◆ END_SOAP_ENVELOPE

const SAML2\SOAPClient::END_SOAP_ENVELOPE = '</soap-env:Body></soap-env:Envelope>'

Definition at line 19 of file SOAPClient.php.

◆ START_SOAP_ENVELOPE

const SAML2\SOAPClient::START_SOAP_ENVELOPE = '<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"><soap-env:Header/><soap-env:Body>'

Definition at line 18 of file SOAPClient.php.


The documentation for this class was generated from the following file: