Skip to content

Instantly share code, notes, and snippets.

@remoharsono
Forked from niczak/gist:2003485
Created August 13, 2019 04:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remoharsono/ec3631383481920aa458762b7caba19c to your computer and use it in GitHub Desktop.
Save remoharsono/ec3631383481920aa458762b7caba19c to your computer and use it in GitHub Desktop.
PHP/SOAP and Microsoft Exchange
<?php
/*
test.php
Proof of concept testing to see if we can get
PHP/SOAP talking to EWS. Thanks to Thomas Rabaix
for his documentation on NTLM auth in SOAP and to
Erik Cederstrand for his article on SOAP/Exchange.
Written: 03/06/2012 - Nicholas Kreidberg
Revised: 03/08/2012 - Nicholas Kreidberg
*/
// NTLMSoapClient class definition
class NTLMSoapClient extends SoapClient
{
function __doRequest($request, $location, $action, $version)
{
$headers = array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "'.$action.'"',
);
$this->__last_request_headers = $headers;
$ch = curl_init($location);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true );
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
// the next option may or may not cause issues with non-XML documents
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
// optional SSL verification
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
// Next lines are for debugging only
printf("Request Array:\n");
print_r($request);
printf("\n<br />Response Array:\n");
print_r($response);
return $response;
}
function __getLastRequestHeaders()
{
return implode("n", $this->__last_request_headers)."n";
}
}
class ExchangeNTLMSoapClient extends NTLMSoapClient
{
protected $user = 'user';
protected $password = 'pass';
}
// NTLMStream class definition
class NTLMStream
{
private $path;
private $mode;
private $options;
private $opened_path;
private $buffer;
private $pos;
public function stream_open($path, $mode, $options, $opened_path) {
echo "[NTLMStream::stream_open] $path , mode=$mode n";
$this->path = $path;
$this->mode = $mode;
$this->options = $options;
$this->opened_path = $opened_path;
$this->createBuffer($path);
return true;
}
public function stream_close() {
echo "[NTLMStream::stream_close] n";
curl_close($this->ch);
}
public function stream_read($count) {
echo "[NTLMStream::stream_read] $count n";
if(strlen($this->buffer) == 0) {
return false;
}
$read = substr($this->buffer,$this->pos, $count);
$this->pos += $count;
return $read;
}
public function stream_write($data) {
echo "[NTLMStream::stream_write] n";
if(strlen($this->buffer) == 0) {
return false;
}
return true;
}
public function stream_eof() {
echo "[NTLMStream::stream_eof] ";
if($this->pos > strlen($this->buffer)) {
echo "true n";
return true;
}
echo "false n";
return false;
}
/* return the position of the current read pointer */
public function stream_tell() {
echo "[NTLMStream::stream_tell] n";
return $this->pos;
}
public function stream_flush() {
echo "[NTLMStream::stream_flush] n";
$this->buffer = null;
$this->pos = null;
}
public function stream_stat() {
echo "[NTLMStream::stream_stat] n";
$this->createBuffer($this->path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
public function url_stat($path, $flags) {
echo "[NTLMStream::url_stat] n";
$this->createBuffer($path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
/* Create the buffer by requesting the url through cURL */
private function createBuffer($path) {
if($this->buffer) {
return;
}
echo "[NTLMStream::createBuffer] create buffer from : $pathn";
$this->ch = curl_init($path);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
echo $this->buffer = curl_exec($this->ch);
echo "[NTLMStream::createBuffer] buffer size : ".strlen($this->buffer)."bytesn";
$this->pos = 0;
}
}
// ExchangeNTLMStream class definition
class ExchangeNTLMStream extends NTLMStream
{
protected $user = 'user';
protected $password = 'pass';
}
stream_wrapper_unregister('https');
stream_wrapper_register('https', 'ExchangeNTLMStream') or die ("Failed to register NTLM protocol.\n");
$wsdl = "./Services.wsdl";
$client = new ExchangeNTLMSoapClient($wsdl);
stream_wrapper_restore('https');
// Show all available functions - for info/debug
//print_r($client->__getFunctions());
// Describe data types - for info/debug
//print_r($client->__getTypes());
// Create a calendar item
$CreateItem->SendMeetingInvitations = "SendToNone";
$CreateItem->SavedItemFolderId->DistinguishedFolderId->Id = "calendar";
$CreateItem->Items->CalendarItem = array();
for($i = 0; $i < 1; $i++)
{
$CreateItem->Items->CalendarItem[$i]->Subject = "Hello from PHP";
$CreateItem->Items->CalendarItem[$i]->ReminderIsSet = false;
$CreateItem->Items->CalendarItem[$i]->Start = "2012-03-08T13:00:00";
$CreateItem->Items->CalendarItem[$i]->End = "2012-03-08T14:00:00";
$CreateItem->Items->CalendarItem[$i]->IsAllDayEvent = false;
$CreateItem->Items->CalendarItem[$i]->LegacyFreeBusyStatus = "Busy";
$CreateItem->Items->CalendarItem[$i]->Location = "Test Location";
}
$result = $client->CreateItem($CreateItem);
printf("\n<br />\nCreateItem Result:<br />\n");
print_r($result);
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment