Esempio n. 1
0
define('PR_INTERNET_REFERENCES', mapi_prop_tag(PT_STRING8, 0x1039));
define('PR_IN_REPLY_TO_ID', mapi_prop_tag(PT_STRING8, 0x1042));
define('PR_INTERNET_MESSAGE_ID', mapi_prop_tag(PT_STRING8, 0x1035));
// for hidden folders
define('PR_ATTR_HIDDEN', mapi_prop_tag(PT_BOOLEAN, 0x10f4));
/**
 * Addressbook detail properties.
 * It is not defined by MAPI, but to keep in sync with the interface of outlook we have to use these
 * properties. Outlook actually uses these properties for it's addressbook details.
 */
define('PR_HOME2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a2f));
define('PR_BUSINESS2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a1b));
define('PR_EMS_AB_PROXY_ADDRESSES', mapi_prop_tag(PT_TSTRING, 0x800f));
define('PR_EMS_AB_PROXY_ADDRESSES_MV', mapi_prop_tag(PT_MV_TSTRING, 0x800f));
define('PR_EMS_AB_MANAGER', mapi_prop_tag(PT_BINARY, 0x8005));
define('PR_EMS_AB_REPORTS', mapi_prop_tag(PT_BINARY, 0x800e));
define('PR_EMS_AB_REPORTS_MV', mapi_prop_tag(PT_MV_BINARY, 0x800e));
define('PR_EMS_AB_IS_MEMBER_OF_DL', mapi_prop_tag(PT_MV_BINARY, 0x8008));
define('PR_EMS_AB_OWNER', mapi_prop_tag(PT_BINARY, 0x800c));
define('PR_EMS_AB_ROOM_CAPACITY', mapi_prop_tag(PT_LONG, 0x807));
define('PR_EMS_AB_TAGGED_X509_CERT', mapi_prop_tag(PT_MV_BINARY, 0x8c6a));
define('PR_EC_ARCHIVE_SERVERS', mapi_prop_tag(PT_MV_TSTRING, 0x67c4));
/* zarafa contacts provider properties */
define('PR_ZC_CONTACT_STORE_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x11));
define('PR_ZC_CONTACT_FOLDER_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x12));
define('PR_ZC_CONTACT_FOLDER_NAMES', mapi_prop_tag(PT_MV_TSTRING, PR_EC_BASE + 0x13));
//Properties defined for Z-Push
define('PR_TODO_ITEM_FLAGS', mapi_prop_tag(PT_LONG, 0xe2b));
define('PR_LOCAL_COMMIT_TIME_MAX', mapi_prop_tag(PT_SYSTIME, 0x670a));
define('PR_DELETED_MSG_COUNT', mapi_prop_tag(PT_LONG, 0x6640));
Esempio n. 2
0
 function _readSingleMapiProp(&$buffer, &$size, &$read, &$mapiprops)
 {
     $propTag = 0;
     $len = 0;
     $origSize = $size;
     $isNamedId = 0;
     $namedProp = 0;
     $count = 0;
     $mvProp = 0;
     $guid = 0;
     if ($size < 8) {
         return MAPI_E_NOT_FOUND;
     }
     $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $propTag);
     if ($hresult !== NOERROR) {
         debugLog("There was an error reading a mapi property tag from the stream.");
         return $hresult;
     }
     $size -= 4;
     //debugLog("mapi prop type:".dechex(mapi_prop_type($propTag)));
     //debugLog("mapi prop tag: 0x".sprintf("%04x", mapi_prop_id($propTag)));
     if (mapi_prop_id($propTag) >= 0x8000) {
         // Named property, first read GUID, then name/id
         if ($size < 24) {
             debugLog("Corrupt guid size for named property:" . dechex($propTag));
             return MAPI_E_CORRUPT_DATA;
         }
         //strip GUID & name/id
         $hresult = $this->_readBuffer($buffer, 16, $guid);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading stream property buffer");
             return $hresult;
         }
         $size -= 16;
         //it is not used and is here only for eventual debugging
         $readableGuid = unpack("VV/v2v/n4n", $guid);
         $readableGuid = sprintf("{%08x-%04x-%04x-%04x-%04x%04x%04x}", $readableGuid['V'], $readableGuid['v1'], $readableGuid['v2'], $readableGuid['n1'], $readableGuid['n2'], $readableGuid['n3'], $readableGuid['n4']);
         //debugLog("guid:$readableGuid");
         $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $isNamedId);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading stream property checksum.");
             return $hresult;
         }
         $size -= 4;
         if ($isNamedId != 0) {
             // A string name follows
             //read length of the property
             $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading mapi property's length");
                 return $hresult;
             }
             $size -= 4;
             if ($size < $len) {
                 return MAPI_E_CORRUPT_DATA;
             }
             //read the name of the property, eg Keywords
             $hresult = $this->_readBuffer($buffer, $len, $namedProp);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading stream property buffer");
                 return $hresult;
             }
             $size -= $len;
             //Re-align
             $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
             $size -= $len & 3 ? 4 - ($len & 3) : 0;
         } else {
             $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $namedProp);
             if ($hresult !== NOERROR) {
                 debugLog("There was an error reading mapi property's length");
                 return $hresult;
             }
             //debugLog("named: 0x".sprintf("%04x", $namedProp));
             $size -= 4;
         }
         if ($this->_store !== false) {
             $named = mapi_getidsfromnames($this->_store, array($namedProp), array(makeguid($readableGuid)));
             $propTag = mapi_prop_tag(mapi_prop_type($propTag), mapi_prop_id($named[0]));
         } else {
             debugLog("Store not available. It is impossible to get named properties");
         }
     }
     //debugLog("mapi prop tag: 0x".sprintf("%04x", mapi_prop_id($propTag))." ".sprintf("%04x", mapi_prop_type($propTag)));
     if ($propTag & MV_FLAG) {
         if ($size < 4) {
             return MAPI_E_CORRUPT_DATA;
         }
         //read the number of properties
         $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $count);
         if ($hresult !== NOERROR) {
             debugLog("There was an error reading number of properties for:" . dechex($propTag));
             return $hresult;
         }
         $size -= 4;
     } else {
         $count = 1;
     }
     for ($mvProp = 0; $mvProp < $count; $mvProp++) {
         switch (mapi_prop_type($propTag) & ~MV_FLAG) {
             case PT_I2:
             case PT_LONG:
                 $hresult = $this->_readBuffer($buffer, 4, $value);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $value = unpack("V", $value);
                 $value = intval($value[1], 16);
                 if ($propTag & MV_FLAG) {
                     $mapiprops[$propTag][] = $value;
                 } else {
                     $mapiprops[$propTag] = $value;
                 }
                 $size -= 4;
                 //debugLog("int or long propvalue:".$value);
                 break;
             case PT_R4:
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 4;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_BOOLEAN:
                 $hresult = $this->_readBuffer($buffer, 4, $mapiprops[$propTag]);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $size -= 4;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_SYSTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //we have to convert the filetime to an unixtime timestamp
                 $filetime = unpack("V2v", $mapiprops[$propTag]);
                 $filetime = hexdec(sprintf("%08x%08x", $filetime['v2'], $filetime['v1']));
                 $filetime = ($filetime - 116444736000000000) / 10000000;
                 $mapiprops[$propTag] = $filetime;
                 // we have to set the start and end times separately because the standard PR_START_DATE and PR_END_DATE aren't enough
                 if ($propTag == PR_START_DATE) {
                     $namedStartTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820d");
                     $mapiprops[$namedStartTime] = $filetime;
                     $namedCommonStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516");
                     $mapiprops[$namedCommonStart] = $filetime;
                 }
                 if ($propTag == PR_END_DATE) {
                     $namedEndTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820e");
                     $mapiprops[$namedEndTime] = $filetime;
                     $namedCommonEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517");
                     $mapiprops[$namedCommonEnd] = $filetime;
                 }
                 $size -= 8;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_DOUBLE:
             case PT_CURRENCY:
             case PT_I8:
             case PT_APPTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 8;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_STRING8:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                     $mapiprops[$namedLocation] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_UNICODE:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 //currently unicode strings are not supported bz mapi_setprops, so we'll use PT_STRING8
                 $propTag = mapi_prop_tag(PT_STRING8, mapi_prop_id($propTag));
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                     $mapiprops[$namedLocation] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                     $mapiprops[$namedLocation] = iconv("UCS-2", "windows-1252", $mapiprops[$namedLocation]);
                 }
                 //convert from unicode to windows encoding
                 if (isset($mapiprops[$propTag])) {
                     $mapiprops[$propTag] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".$mapiprops[$propTag]);
                 break;
             case PT_OBJECT:
                 // PST sends PT_OBJECT data. Treat as PT_BINARY
             // PST sends PT_OBJECT data. Treat as PT_BINARY
             case PT_BINARY:
                 if ($size < ZP_BYTE) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->_readFromTnefStream($buffer, ZP_DWORD, $len);
                 if ($hresult !== NOERROR) {
                     debugLog("There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if (mapi_prop_type($propTag) == PT_OBJECT) {
                     // TODO: IMessage guid [ 0x00020307 C000 0000 0000 0000 00 00 00 46 ]
                     $buffer = substr($buffer, 16);
                     $size -= 16;
                     $len -= 16;
                 }
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->_readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         debugLog("There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 //debugLog("propvalue:".bin2hex($mapiprops[$propTag]));
                 break;
             default:
                 return MAPI_E_INVALID_PARAMETER;
                 break;
         }
     }
     return NOERROR;
 }
Esempio n. 3
0
 /**
  * Create a MAPI restriction in order to check if a contact has a picture
  *
  * @access public
  * @return array
  */
 public static function GetContactPicRestriction()
 {
     return array(RES_PROPERTY, array(RELOP => RELOP_EQ, ULPROPTAG => mapi_prop_tag(PT_BOOLEAN, 0x7fff), VALUE => true));
 }
Esempio n. 4
0
/**
 * Check wether a call to mapi_getprops returned errors for some properties.
 * mapi_getprops function tries to get values of properties requested but somehow if
 * if a property value can not be fetched then it changes type of property tag as PT_ERROR
 * and returns error for that particular property, probable errors
 * that can be returned as value can be MAPI_E_NOT_FOUND, MAPI_E_NOT_ENOUGH_MEMORY
 *
 * @param long $property Property to check for error
 * @param Array $propArray An array of properties
 * @return mixed Gives back false when there is no error, if there is, gives the error
 */
function propIsError($property, $propArray)
{
    if (array_key_exists(mapi_prop_tag(PT_ERROR, mapi_prop_id($property)), $propArray)) {
        return $propArray[mapi_prop_tag(PT_ERROR, mapi_prop_id($property))];
    } else {
        return false;
    }
}
Esempio n. 5
0
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
* ************************************************/
include_once "syncworker.php";
include_once 'mapi/mapi.util.php';
include_once 'mapi/mapidefs.php';
include_once 'mapi/mapitags.php';
include_once 'mapi/mapicode.php';
include_once 'mapi/mapiguid.php';
define('PR_EMS_AB_THUMBNAIL_PHOTO', mapi_prop_tag(PT_BINARY, 0x8c9e));
class Kopano extends SyncWorker
{
    const NAME = "Z-Push Kopano GAB Sync";
    const VERSION = "1.1";
    private $session;
    private $defaultstore;
    private $store;
    private $mainUser;
    private $targetStore;
    private $folderCache;
    private $storeCache;
    private $mapiprops;
    /**
     * Constructor
     */
Esempio n. 6
0
 function SendMail($rfc822, $forward = false, $reply = false, $parent = false)
 {
     $mimeParams = array('decode_headers' => false, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\r\n", 'charset' => 'utf-8');
     $mimeObject = new Mail_mimeDecode($mimeParams['input'], $mimeParams['crlf']);
     $message = $mimeObject->decode($mimeParams);
     // Open the outbox and create the message there
     $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID));
     if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) {
         debugLog("Outbox not found to create message");
         return false;
     }
     $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
     if (!$outbox) {
         debugLog("Unable to open outbox");
         return false;
     }
     $mapimessage = mapi_folder_createmessage($outbox);
     mapi_setprops($mapimessage, array(PR_SUBJECT => u2w($mimeObject->_decodeHeader($message->headers["subject"])), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time()));
     if (isset($message->headers["x-priority"])) {
         switch ($message->headers["x-priority"]) {
             case 1:
             case 2:
                 $priority = PRIO_URGENT;
                 $importance = IMPORTANCE_HIGH;
                 break;
             case 4:
             case 5:
                 $priority = PRIO_NONURGENT;
                 $importance = IMPORTANCE_LOW;
                 break;
             case 3:
             default:
                 $priority = PRIO_NORMAL;
                 $importance = IMPORTANCE_NORMAL;
                 break;
         }
         mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority));
     }
     $addresses = array();
     $toaddr = $ccaddr = $bccaddr = array();
     if (isset($message->headers["to"])) {
         $toaddr = Mail_RFC822::parseAddressList($message->headers["to"]);
     }
     if (isset($message->headers["cc"])) {
         $ccaddr = Mail_RFC822::parseAddressList($message->headers["cc"]);
     }
     if (isset($message->headers["bcc"])) {
         $bccaddr = Mail_RFC822::parseAddressList($message->headers["bcc"]);
     }
     // Add recipients
     $recips = array();
     if (isset($toaddr)) {
         foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) {
             foreach ($addrlist as $addr) {
                 $mapirecip[PR_ADDRTYPE] = "SMTP";
                 $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host;
                 if (isset($addr->personal) && strlen($addr->personal) > 0) {
                     $mapirecip[PR_DISPLAY_NAME] = u2w($mimeObject->_decodeHeader($addr->personal));
                 } else {
                     $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS];
                 }
                 $mapirecip[PR_RECIPIENT_TYPE] = $type;
                 $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]);
                 array_push($recips, $mapirecip);
             }
         }
     }
     mapi_message_modifyrecipients($mapimessage, 0, $recips);
     // Loop through subparts. We currently only support real single-level
     // multiparts and partly multipart/related/mixed for attachments.
     // The PDA currently only does this because you are adding
     // an attachment and the type will be multipart/mixed or multipart/alternative.
     $body = "";
     if ($message->ctype_primary == "multipart" && ($message->ctype_secondary == "mixed" || $message->ctype_secondary == "alternative")) {
         foreach ($message->parts as $part) {
             if ($part->ctype_primary == "text" && $part->ctype_secondary == "plain" && isset($part->body)) {
                 // discard any other kind of text, like html
                 $body .= u2w($part->body);
                 // assume only one text body
             } elseif ($part->ctype_primary == "ms-tnef" || $part->ctype_secondary == "ms-tnef") {
                 $zptnef = new ZPush_tnef($this->_defaultstore);
                 $mapiprops = array();
                 $zptnef->extractProps($part->body, $mapiprops);
                 if (is_array($mapiprops) && !empty($mapiprops)) {
                     //check if it is a recurring item
                     $tnefrecurr = GetPropIDFromString($this->_defaultstore, "PT_BOOLEAN:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x5");
                     if (isset($mapiprops[$tnefrecurr])) {
                         $this->_handleRecurringItem($mapimessage, $mapiprops);
                     }
                     mapi_setprops($mapimessage, $mapiprops);
                 } else {
                     debugLog("TNEF: Mapi props array was empty");
                 }
             } elseif ($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "related")) {
                 if (is_array($part->parts)) {
                     foreach ($part->parts as $part2) {
                         if (isset($part2->disposition) && ($part2->disposition == "inline" || $part2->disposition == "attachment")) {
                             $this->_storeAttachment($mapimessage, $part2);
                         }
                     }
                 }
             } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "calendar") {
                 $zpical = new ZPush_ical($this->_defaultstore);
                 $mapiprops = array();
                 $zpical->extractProps($part->body, $mapiprops);
                 if (is_array($mapiprops) && !empty($mapiprops)) {
                     mapi_setprops($mapimessage, $mapiprops);
                 } else {
                     debugLog("ICAL: Mapi props array was empty");
                 }
             } else {
                 $this->_storeAttachment($mapimessage, $part);
             }
         }
     } else {
         $body = u2w($message->body);
     }
     if ($forward) {
         $orig = $forward;
     }
     if ($reply) {
         $orig = $reply;
     }
     if (isset($orig) && $orig) {
         // Append the original text body for reply/forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         if ($fwmessage) {
             //update icon when forwarding or replying message
             if ($forward) {
                 mapi_setprops($fwmessage, array(PR_ICON_INDEX => 262));
             } elseif ($reply) {
                 mapi_setprops($fwmessage, array(PR_ICON_INDEX => 261));
             }
             mapi_savechanges($fwmessage);
             $stream = mapi_openproperty($fwmessage, PR_BODY, IID_IStream, 0, 0);
             $fwbody = "";
             while (1) {
                 $data = mapi_stream_read($stream, 1024);
                 if (strlen($data) == 0) {
                     break;
                 }
                 $fwbody .= $data;
             }
             if (strlen($body) > 0) {
                 if ($forward) {
                     // During a forward, we have to add the forward header ourselves. This is because
                     // normally the forwarded message is added as an attachment. However, we don't want this
                     // because it would be rather complicated to copy over the entire original message due
                     // to the lack of IMessage::CopyTo ..
                     $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME));
                     $body .= "\r\n\r\n";
                     $body .= "-----Original Message-----\r\n";
                     if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) {
                         $body .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) {
                         $body .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) {
                         $body .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) {
                         $body .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_SUBJECT])) {
                         $body .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n";
                     }
                     $body .= "\r\n";
                 }
                 $body .= $fwbody;
             }
         } else {
             debugLog("Unable to open item with id {$orig} for forward/reply");
         }
     }
     if ($forward) {
         // Add attachments from the original message in a forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         $attachtable = mapi_message_getattachmenttable($fwmessage);
         $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
         foreach ($rows as $row) {
             if (isset($row[PR_ATTACH_NUM])) {
                 $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]);
                 $newattach = mapi_message_createattach($mapimessage);
                 // Copy all attachments from old to new attachment
                 $attachprops = mapi_getprops($attach);
                 mapi_setprops($newattach, $attachprops);
                 if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) {
                     // Data is in a stream
                     $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN);
                     $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE);
                     while (1) {
                         $data = mapi_stream_read($srcstream, 4096);
                         if (strlen($data) == 0) {
                             break;
                         }
                         mapi_stream_write($dststream, $data);
                     }
                     mapi_stream_commit($dststream);
                 }
                 mapi_savechanges($newattach);
             }
         }
     }
     mapi_setprops($mapimessage, array(PR_BODY => $body));
     mapi_savechanges($mapimessage);
     mapi_message_submitmessage($mapimessage);
     return true;
 }
Esempio n. 7
0
    print "Please enable php-mapi module for commandline usage";
    exit;
}
define('PT_BOOLEAN', 11);
/* 16-bit boolean (non-zero true) */
define('PT_STRING8', 30);
/* Null terminated 8-bit character string */
define('PT_TSTRING', PT_STRING8);
define('PT_BINARY', 258);
/* Uninterpreted (counted byte array) */
define('PT_SYSTIME', 64);
/* FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601 */
define('PR_DEFAULT_STORE', mapi_prop_tag(PT_BOOLEAN, 0x3400));
define('PR_ENTRYID', mapi_prop_tag(PT_BINARY, 0xfff));
define('PR_IPM_WASTEBASKET_ENTRYID', mapi_prop_tag(PT_BINARY, 0x35e3));
define('PR_CREATION_TIME', mapi_prop_tag(PT_SYSTIME, 0x3007));
function greaterDate($start_date, $daysBeforeDeleted)
{
    return strtotime($start_date) - strtotime(date('Y-m-d G:i:s', strtotime("-{$daysBeforeDeleted} days"))) < 0 ? 1 : 0;
}
// Add the SVN revision number to the version
$mapi_version = str_replace('-', '.', phpversion('mapi'));
// Log in to Zarafa server
if (version_compare($mapi_version, '7.2.0.46424', '>=')) {
    $l_rSession = mapi_logon_zarafa($l_sUsername, $l_sPassword, $l_sServer, NULL, NULL, NULL, NULL);
} else {
    $l_rSession = mapi_logon_zarafa($l_sUsername, $l_sPassword, $l_sServer);
}
echo (mapi_last_hresult() == 0 ? "Logged in successfully" : "Some error in login") . "\n";
// Get a table with the message stores within this session
$l_rTableStores = mapi_getmsgstorestable($l_rSession);
Esempio n. 8
0
 /**
  * Reads a single mapi prop.
  *
  * @param string        &$buffer
  * @param int           $size
  * @param mixed         &$read
  * @param array         &$mapiprops
  *
  * @access private
  * @return int
  */
 private function readSingleMapiProp(&$buffer, &$size, &$read, &$mapiprops)
 {
     $propTag = 0;
     $len = 0;
     $origSize = $size;
     $isNamedId = 0;
     $namedProp = 0;
     $count = 0;
     $mvProp = 0;
     $guid = 0;
     if ($size < 8) {
         return MAPI_E_NOT_FOUND;
     }
     $hresult = $this->readFromTnefStream($buffer, self::DWORD, $propTag);
     if ($hresult !== NOERROR) {
         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading a mapi property tag from the stream.");
         return $hresult;
     }
     $size -= 4;
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop type:" . dechex(mapi_prop_type($propTag)));
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop tag: 0x" . sprintf("%04x", mapi_prop_id($propTag)));
     if (mapi_prop_id($propTag) >= 0x8000) {
         // Named property, first read GUID, then name/id
         if ($size < 24) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: Corrupt guid size for named property:" . dechex($propTag));
             return MAPI_E_CORRUPT_DATA;
         }
         //strip GUID & name/id
         $hresult = $this->readBuffer($buffer, 16, $guid);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
             return $hresult;
         }
         $size -= 16;
         //it is not used and is here only for eventual debugging
         $readableGuid = unpack("VV/v2v/n4n", $guid);
         $readableGuid = sprintf("{%08x-%04x-%04x-%04x-%04x%04x%04x}", $readableGuid['V'], $readableGuid['v1'], $readableGuid['v2'], $readableGuid['n1'], $readableGuid['n2'], $readableGuid['n3'], $readableGuid['n4']);
         ZLog::Write(LOGLEVEL_DEBUG, "TNEF: guid:{$readableGuid}");
         $hresult = $this->readFromTnefStream($buffer, self::DWORD, $isNamedId);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property checksum.");
             return $hresult;
         }
         $size -= 4;
         if ($isNamedId != 0) {
             // A string name follows
             //read length of the property
             $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                 return $hresult;
             }
             $size -= 4;
             if ($size < $len) {
                 return MAPI_E_CORRUPT_DATA;
             }
             //read the name of the property, eg Keywords
             $hresult = $this->readBuffer($buffer, $len, $namedProp);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                 return $hresult;
             }
             $size -= $len;
             //Re-align
             $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
             $size -= $len & 3 ? 4 - ($len & 3) : 0;
         } else {
             $hresult = $this->readFromTnefStream($buffer, self::DWORD, $namedProp);
             if ($hresult !== NOERROR) {
                 ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                 return $hresult;
             }
             ZLog::Write(LOGLEVEL_DEBUG, "TNEF: named: 0x" . sprintf("%04x", $namedProp));
             $size -= 4;
         }
         if ($this->store !== false) {
             $named = mapi_getidsfromnames($this->store, array($namedProp), array(makeguid($readableGuid)));
             $propTag = mapi_prop_tag(mapi_prop_type($propTag), mapi_prop_id($named[0]));
         } else {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: Store not available. It is impossible to get named properties");
         }
     }
     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: mapi prop tag: 0x" . sprintf("%04x", mapi_prop_id($propTag)) . " " . sprintf("%04x", mapi_prop_type($propTag)));
     if ($propTag & MV_FLAG) {
         if ($size < 4) {
             return MAPI_E_CORRUPT_DATA;
         }
         //read the number of properties
         $hresult = $this->readFromTnefStream($buffer, self::DWORD, $count);
         if ($hresult !== NOERROR) {
             ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading number of properties for:" . dechex($propTag));
             return $hresult;
         }
         $size -= 4;
     } else {
         $count = 1;
     }
     for ($mvProp = 0; $mvProp < $count; $mvProp++) {
         switch (mapi_prop_type($propTag) & ~MV_FLAG) {
             case PT_I2:
             case PT_LONG:
                 $hresult = $this->readBuffer($buffer, 4, $value);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $value = unpack("V", $value);
                 $value = intval($value[1], 16);
                 if ($propTag & MV_FLAG) {
                     $mapiprops[$propTag][] = $value;
                 } else {
                     $mapiprops[$propTag] = $value;
                 }
                 $size -= 4;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: int or long propvalue:" . $value);
                 break;
             case PT_R4:
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 4;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_BOOLEAN:
                 $hresult = $this->readBuffer($buffer, 4, $mapiprops[$propTag]);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                     return $hresult;
                 }
                 $size -= 4;
                 //reported by dw2412
                 //cast to integer as it evaluates to 1 or 0 because
                 //a non empty string evaluates to true :(
                 $mapiprops[$propTag] = (int) bin2hex($mapiprops[$propTag][0]);
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_SYSTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //we have to convert the filetime to an unixtime timestamp
                 $filetime = unpack("V2v", $mapiprops[$propTag]);
                 //php on 64-bit systems converts unsigned values differently than on 32 bit systems
                 //we need this "fix" in order to get the same values on both types of systems
                 $filetime['v2'] = substr(sprintf("%08x", $filetime['v2']), -8);
                 $filetime['v1'] = substr(sprintf("%08x", $filetime['v1']), -8);
                 $filetime = hexdec($filetime['v2'] . $filetime['v1']);
                 $filetime = ($filetime - 116444736000000000) / 10000000;
                 $mapiprops[$propTag] = $filetime;
                 // we have to set the start and end times separately because the standard PR_START_DATE and PR_END_DATE aren't enough
                 if ($propTag == PR_START_DATE) {
                     $mapiprops[$this->props["starttime"]] = $mapiprops[$this->props["commonstart"]] = $filetime;
                 }
                 if ($propTag == PR_END_DATE) {
                     $mapiprops[$this->props["endtime"]] = $mapiprops[$this->props["commonend"]] = $filetime;
                 }
                 $size -= 8;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_DOUBLE:
             case PT_CURRENCY:
             case PT_I8:
             case PT_APPTIME:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, 8, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= 8;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_STRING8:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $mapiprops[$this->props["location"]] = $mapiprops[$propTag];
                     unset($mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 break;
             case PT_UNICODE:
                 if ($size < 8) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 //currently unicode strings are not supported bz mapi_setprops, so we'll use PT_STRING8
                 $propTag = mapi_prop_tag(PT_STRING8, mapi_prop_id($propTag));
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 //location fix. it looks like tnef uses this value for location
                 if (mapi_prop_id($propTag) == 0x8342) {
                     $mapiprops[$this->props["location"]] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                     unset($mapiprops[$propTag]);
                 }
                 //convert from unicode to windows encoding
                 if (isset($mapiprops[$propTag])) {
                     $mapiprops[$propTag] = iconv("UCS-2", "windows-1252", $mapiprops[$propTag]);
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 if (isset($mapiprops[$propTag])) {
                     ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . $mapiprops[$propTag]);
                 }
                 break;
             case PT_OBJECT:
                 // PST sends PT_OBJECT data. Treat as PT_BINARY
             // PST sends PT_OBJECT data. Treat as PT_BINARY
             case PT_BINARY:
                 if ($size < self::BYTE) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 // Skip next 4 bytes, it's always '1' (ULONG)
                 $buffer = substr($buffer, 4);
                 $size -= 4;
                 //read length of the property
                 $hresult = $this->readFromTnefStream($buffer, self::DWORD, $len);
                 if ($hresult !== NOERROR) {
                     ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading mapi property's length");
                     return $hresult;
                 }
                 $size -= 4;
                 if (mapi_prop_type($propTag) == PT_OBJECT) {
                     // IMessage guid [ 0x00020307 C000 0000 0000 0000 00 00 00 46 ]
                     $buffer = substr($buffer, 16);
                     $size -= 16;
                     $len -= 16;
                 }
                 if ($size < $len) {
                     return MAPI_E_CORRUPT_DATA;
                 }
                 if ($propTag & MV_FLAG) {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag][]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 } else {
                     $hresult = $this->readBuffer($buffer, $len, $mapiprops[$propTag]);
                     if ($hresult !== NOERROR) {
                         ZLog::Write(LOGLEVEL_WARN, "TNEF: There was an error reading stream property buffer");
                         return $hresult;
                     }
                 }
                 $size -= $len;
                 //Re-align
                 $buffer = substr($buffer, $len & 3 ? 4 - ($len & 3) : 0);
                 $size -= $len & 3 ? 4 - ($len & 3) : 0;
                 ZLog::Write(LOGLEVEL_DEBUG, "TNEF: propvalue:" . bin2hex($mapiprops[$propTag]));
                 break;
             default:
                 return MAPI_E_INVALID_PARAMETER;
                 break;
         }
     }
     return NOERROR;
 }
}
// The purpose of this script is to process the unprocessed meeting requests in the inbox folder
$l_sUsername = $argv[1];
$l_sPassword = '';
$l_sServer = 'file:///var/run/zarafa';
// Include MAPI PHP-EXT
define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . "/");
set_include_path(BASE_PATH . PATH_SEPARATOR . "/usr/share/php/");
require "mapi/mapi.util.php";
require "mapi/mapicode.php";
require "mapi/mapidefs.php";
require "mapi/mapitags.php";
require "mapi/mapiguid.php";
require "mapi/class.meetingrequest.php";
require "mapi/class.freebusypublish.php";
define('PR_PROCESSED', mapi_prop_tag(PT_BOOLEAN, 0x7d01));
if (!function_exists('hex2bin')) {
    function hex2bin($data)
    {
        return pack("H*", $data);
    }
}
/**
 * Publishing the FreeBusy information of the default calendar. The 
 * folderentryid argument is used to check if the default calendar 
 * should be updated or not.
 * 
 * @param $store MAPIobject Store object of the store that needs publishing
 * @param $folderentryid binary entryid of the folder that needs to be updated.
 */
function publishFreeBusy($store, $l_rSession, $folderentryid = false)
Esempio n. 10
0
define('PR_ATTR_HIDDEN', mapi_prop_tag(PT_BOOLEAN, 0x10f4));
/**
 * Addressbook detail properties.
 * It is not defined by MAPI, but to keep in sync with the interface of outlook we have to use these
 * properties. Outlook actually uses these properties for it's addressbook details.
 */
define('PR_HOME2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a2f));
define('PR_BUSINESS2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a1b));
define('PR_EMS_AB_PROXY_ADDRESSES', mapi_prop_tag(PT_TSTRING, 0x800f));
define('PR_EMS_AB_PROXY_ADDRESSES_MV', mapi_prop_tag(PT_MV_TSTRING, 0x800f));
define('PR_EMS_AB_MANAGER', mapi_prop_tag(PT_BINARY, 0x8005));
define('PR_EMS_AB_REPORTS', mapi_prop_tag(PT_BINARY, 0x800e));
define('PR_EMS_AB_REPORTS_MV', mapi_prop_tag(PT_MV_BINARY, 0x800e));
define('PR_EMS_AB_IS_MEMBER_OF_DL', mapi_prop_tag(PT_MV_BINARY, 0x8008));
define('PR_EMS_AB_OWNER', mapi_prop_tag(PT_BINARY, 0x800c));
define('PR_EMS_AB_ROOM_CAPACITY', mapi_prop_tag(PT_LONG, 0x807));
define('PR_EMS_AB_TAGGED_X509_CERT', mapi_prop_tag(PT_MV_BINARY, 0x8c6a));
define('PR_EMS_AB_THUMBNAIL_PHOTO', mapi_prop_tag(PT_MV_BINARY, 0x8c9e));
define('PR_EC_ARCHIVE_SERVERS', mapi_prop_tag(PT_MV_TSTRING, 0x67c4));
/* zarafa contacts provider properties */
define('PR_ZC_CONTACT_STORE_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x11));
define('PR_ZC_CONTACT_FOLDER_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x12));
define('PR_ZC_CONTACT_FOLDER_NAMES', mapi_prop_tag(PT_MV_TSTRING, PR_EC_BASE + 0x13));
/* zarafa specific properties for optimization of imap functionality */
define('PR_EC_IMAP_EMAIL', mapi_prop_tag(PT_BINARY, PR_EC_BASE + 0x8c));
//the complete rfc822 email
define('PR_EC_IMAP_EMAIL_SIZE', mapi_prop_tag(PT_LONG, PR_EC_BASE + 0x8d));
define('PR_EC_IMAP_BODY', mapi_prop_tag(PT_STRING8, PR_EC_BASE + 0x8e));
//simplified bodystructure (mostly unused by clients)
define('PR_EC_IMAP_BODYSTRUCTURE', mapi_prop_tag(PT_STRING8, PR_EC_BASE + 0x8f));
//extended bodystructure (often used by clients)
Esempio n. 11
0
 function SendMail($rfc822, $forward = false, $reply = false, $parent = false)
 {
     $message = Mail_mimeDecode::decode(array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'input' => $rfc822, 'crlf' => "\r\n", 'charset' => 'utf-8'));
     // Open the outbox and create the message there
     $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID));
     if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) {
         debugLog("Outbox not found to create message");
         return false;
     }
     $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
     if (!$outbox) {
         debugLog("Unable to open outbox");
         return false;
     }
     $mapimessage = mapi_folder_createmessage($outbox);
     mapi_setprops($mapimessage, array(PR_SUBJECT => u2w($message->headers["subject"]), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time()));
     if (isset($message->headers["x-priority"])) {
         switch ($message->headers["x-priority"]) {
             case 1:
             case 2:
                 $priority = PRIO_URGENT;
                 $importance = IMPORTANCE_HIGH;
                 break;
             case 4:
             case 5:
                 $priority = PRIO_NONURGENT;
                 $importance = IMPORTANCE_LOW;
                 break;
             case 3:
             default:
                 $priority = PRIO_NORMAL;
                 $importance = IMPORTANCE_NORMAL;
                 break;
         }
         mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority));
     }
     $addresses = array();
     $toaddr = $ccaddr = $bccaddr = array();
     if (isset($message->headers["to"])) {
         $toaddr = Mail_RFC822::parseAddressList($message->headers["to"]);
     }
     if (isset($message->headers["cc"])) {
         $ccaddr = Mail_RFC822::parseAddressList($message->headers["cc"]);
     }
     if (isset($message->headers["bcc"])) {
         $bccaddr = Mail_RFC822::parseAddressList($message->headers["bcc"]);
     }
     // Add recipients
     $recips = array();
     if (isset($toaddr)) {
         foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) {
             foreach ($addrlist as $addr) {
                 $mapirecip[PR_ADDRTYPE] = "SMTP";
                 $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host;
                 if (isset($addr->personal) && strlen($addr->personal) > 0) {
                     $mapirecip[PR_DISPLAY_NAME] = u2w($addr->personal);
                 } else {
                     $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS];
                 }
                 $mapirecip[PR_RECIPIENT_TYPE] = $type;
                 $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]);
                 array_push($recips, $mapirecip);
             }
         }
     }
     mapi_message_modifyrecipients($mapimessage, 0, $recips);
     // Loop through subparts. We currently only support single-level
     // multiparts. The PDA currently only does this because you are adding
     // an attachment and the type will be multipart/mixed.
     if ($message->ctype_primary == "multipart" && $message->ctype_secondary == "mixed") {
         foreach ($message->parts as $part) {
             if ($part->ctype_primary == "text") {
                 $body = u2w($part->body);
             } else {
                 // attachment
                 $attach = mapi_message_createattach($mapimessage);
                 // Filename is present in both Content-Type: name=.. and in Content-Disposition: filename=
                 if (isset($part->ctype_parameters["name"])) {
                     $filename = $part->ctype_parameters["name"];
                 } else {
                     if (isset($part->d_parameters["name"])) {
                         $filename = $part->d_parameters["filename"];
                     } else {
                         $filename = "untitled";
                     }
                 }
                 // Set filename and attachment type
                 mapi_setprops($attach, array(PR_ATTACH_LONG_FILENAME => u2w($filename), PR_ATTACH_METHOD => ATTACH_BY_VALUE));
                 // Set attachment data
                 mapi_setprops($attach, array(PR_ATTACH_DATA_BIN => $part->body));
                 // Set MIME type
                 mapi_setprops($attach, array(PR_ATTACH_MIME_TAG => $part->ctype_primary . "/" . $part->ctype_secondary));
                 mapi_savechanges($attach);
             }
         }
     } else {
         $body = u2w($message->body);
     }
     if ($forward) {
         $orig = $forward;
     }
     if ($reply) {
         $orig = $reply;
     }
     if (isset($orig) && $orig) {
         // Append the original text body for reply/forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         if ($fwmessage) {
             $messageprops = mapi_getprops($fwmessage, array(PR_BODY));
             if (isset($messageprops[PR_BODY])) {
                 if ($forward) {
                     // During a forward, we have to add the forward header ourselves. This is because
                     // normally the forwarded message is added as an attachment. However, we don't want this
                     // because it would be rather complicated to copy over the entire original message due
                     // to the lack of IMessage::CopyTo ..
                     $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME));
                     $body .= "\r\n\r\n";
                     $body .= "-----Original Message-----\r\n";
                     if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) {
                         $body .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) {
                         $body .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) {
                         $body .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) {
                         $body .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n";
                     }
                     if (isset($fwmessageprops[PR_SUBJECT])) {
                         $body .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n";
                     }
                     $body .= "\r\n";
                 }
                 $body .= $messageprops[PR_BODY];
             }
         } else {
             debugLog("Unable to open item with id {$orig} for forward/reply");
         }
     }
     if ($forward) {
         // Add attachments from the original message in a forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         $attachtable = mapi_message_getattachmenttable($fwmessage);
         $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
         foreach ($rows as $row) {
             if (isset($row[PR_ATTACH_NUM])) {
                 $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]);
                 $newattach = mapi_message_createattach($mapimessage);
                 // Copy all attachments from old to new attachment
                 $attachprops = mapi_getprops($attach);
                 mapi_setprops($newattach, $attachprops);
                 if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) {
                     // Data is in a stream
                     $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN);
                     $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE);
                     while (1) {
                         $data = mapi_stream_read($srcstream, 4096);
                         if (strlen($data) == 0) {
                             break;
                         }
                         mapi_stream_write($dststream, $data);
                     }
                     mapi_stream_commit($dststream);
                 }
                 mapi_savechanges($newattach);
             }
         }
     }
     mapi_setprops($mapimessage, array(PR_BODY => $body));
     mapi_savechanges($mapimessage);
     mapi_message_submitmessage($mapimessage);
     return true;
 }
Esempio n. 12
0
define('PR_SCHDINFO_DELEGATE_NAMES', mapi_prop_tag(PT_MV_STRING8, 0x6844));
define('PR_DELEGATED_BY_RULE', mapi_prop_tag(PT_BOOLEAN, 0x3fe3));
// properties required in Reply mail.
define('PR_INTERNET_REFERENCES', mapi_prop_tag(PT_STRING8, 0x1039));
define('PR_IN_REPLY_TO_ID', mapi_prop_tag(PT_STRING8, 0x1042));
define('PR_INTERNET_MESSAGE_ID', mapi_prop_tag(PT_STRING8, 0x1035));
// for hidden folders
define('PR_ATTR_HIDDEN', mapi_prop_tag(PT_BOOLEAN, 0x10f4));
/**
 * Addressbook detail properties.
 * It is not defined by MAPI, but to keep in sync with the interface of outlook we have to use these
 * properties. Outlook actually uses these properties for it's addressbook details.
 */
define('PR_HOME2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a2f));
define('PR_BUSINESS2_TELEPHONE_NUMBER_MV', mapi_prop_tag(PT_MV_TSTRING, 0x3a1b));
define('PR_EMS_AB_PROXY_ADDRESSES', mapi_prop_tag(PT_TSTRING, 0x800f));
define('PR_EMS_AB_PROXY_ADDRESSES_MV', mapi_prop_tag(PT_MV_TSTRING, 0x800f));
define('PR_EMS_AB_MANAGER', mapi_prop_tag(PT_BINARY, 0x8005));
define('PR_EMS_AB_REPORTS', mapi_prop_tag(PT_BINARY, 0x800e));
define('PR_EMS_AB_REPORTS_MV', mapi_prop_tag(PT_MV_BINARY, 0x800e));
define('PR_EMS_AB_IS_MEMBER_OF_DL', mapi_prop_tag(PT_MV_BINARY, 0x8008));
define('PR_EMS_AB_OWNER', mapi_prop_tag(PT_BINARY, 0x800c));
define('PR_EMS_AB_ROOM_CAPACITY', mapi_prop_tag(PT_LONG, 0x807));
define('PR_EC_ARCHIVE_SERVERS', mapi_prop_tag(PT_MV_TSTRING, 0x67c4));
/* zarafa contacts provider properties */
define('PR_ZC_CONTACT_STORE_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x11));
define('PR_ZC_CONTACT_FOLDER_ENTRYIDS', mapi_prop_tag(PT_MV_BINARY, PR_EC_BASE + 0x12));
define('PR_ZC_CONTACT_FOLDER_NAMES', mapi_prop_tag(PT_MV_TSTRING, PR_EC_BASE + 0x13));
//Properties defined for Z-Push
define('PR_TODO_ITEM_FLAGS', mapi_prop_tag(PT_LONG, 0xe2b));
function mapitags()
{
    define('PR_ENTRYID', mapi_prop_tag(PT_BINARY, 0xfff));
    define('PR_MDB_PROVIDER', mapi_prop_tag(PT_BINARY, 0x3414));
    define('PR_IPM_CONTACT_ENTRYID', mapi_prop_tag(PT_BINARY, 0x36d1));
    define('PR_IPM_PUBLIC_FOLDERS_ENTRYID', mapi_prop_tag(PT_BINARY, 0x6631));
    define('PR_DISPLAY_NAME', mapi_prop_tag(PT_TSTRING, 0x3001));
    define('PR_SUBJECT', mapi_prop_tag(PT_TSTRING, 0x37));
    define('PR_COMPANY_NAME', mapi_prop_tag(PT_TSTRING, 0x3a16));
    define('PR_BUSINESS_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a08));
    define('PR_OFFICE_TELEPHONE_NUMBER', PR_BUSINESS_TELEPHONE_NUMBER);
    define('PR_MOBILE_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1c));
    define('PR_CELLULAR_TELEPHONE_NUMBER', PR_MOBILE_TELEPHONE_NUMBER);
    define('PR_BUSINESS_FAX_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a24));
    define('PR_MESSAGE_CLASS', mapi_prop_tag(PT_TSTRING, 0x1a));
    define('PR_ICON_INDEX', mapi_prop_tag(PT_LONG, 0x1080));
    define('PR_GIVEN_NAME', mapi_prop_tag(PT_TSTRING, 0x3a06));
    define('PR_MIDDLE_NAME', mapi_prop_tag(PT_TSTRING, 0x3a44));
    define('PR_SURNAME', mapi_prop_tag(PT_TSTRING, 0x3a11));
    define('PR_HOME_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a09));
    define('PR_TITLE', mapi_prop_tag(PT_TSTRING, 0x3a17));
    define('PR_DEPARTMENT_NAME', mapi_prop_tag(PT_TSTRING, 0x3a18));
    define('PR_OFFICE_LOCATION', mapi_prop_tag(PT_TSTRING, 0x3a19));
    define('PR_PROFESSION', mapi_prop_tag(PT_TSTRING, 0x3a46));
    define('PR_MANAGER_NAME', mapi_prop_tag(PT_TSTRING, 0x3a4e));
    define('PR_ASSISTANT', mapi_prop_tag(PT_TSTRING, 0x3a30));
    define('PR_NICKNAME', mapi_prop_tag(PT_TSTRING, 0x3a4f));
    define('PR_DISPLAY_NAME_PREFIX', mapi_prop_tag(PT_TSTRING, 0x3a45));
    define('PR_SPOUSE_NAME', mapi_prop_tag(PT_TSTRING, 0x3a48));
    define('PR_GENERATION', mapi_prop_tag(PT_TSTRING, 0x3a05));
    define('PR_BIRTHDAY', mapi_prop_tag(PT_SYSTIME, 0x3a42));
    define('PR_WEDDING_ANNIVERSARY', mapi_prop_tag(PT_SYSTIME, 0x3a41));
    define('PR_SENSITIVITY', mapi_prop_tag(PT_LONG, 0x36));
    define('PR_BUSINESS_HOME_PAGE', mapi_prop_tag(PT_TSTRING, 0x3a51));
    define('PR_LAST_MODIFICATION_TIME', mapi_prop_tag(PT_SYSTIME, 0x3008));
    define('PR_ASSISTANT_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a2e));
    define('PR_BUSINESS2_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1b));
    define('PR_CALLBACK_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a02));
    define('PR_CAR_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1e));
    define('PR_COMPANY_MAIN_PHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a57));
    define('PR_HOME2_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a2f));
    define('PR_HOME_FAX_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a25));
    define('PR_ISDN_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a2d));
    define('PR_OTHER_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1f));
    define('PR_PAGER_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a21));
    define('PR_PRIMARY_FAX_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a23));
    define('PR_PRIMARY_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1a));
    define('PR_RADIO_TELEPHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a1d));
    define('PR_TELEX_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a2c));
    define('PR_TTYTDD_PHONE_NUMBER', mapi_prop_tag(PT_TSTRING, 0x3a4b));
    define('PR_HOME_ADDRESS_STREET', mapi_prop_tag(PT_TSTRING, 0x3a5d));
    define('PR_HOME_ADDRESS_CITY', mapi_prop_tag(PT_TSTRING, 0x3a59));
    define('PR_HOME_ADDRESS_STATE_OR_PROVINCE', mapi_prop_tag(PT_TSTRING, 0x3a5c));
    define('PR_HOME_ADDRESS_POSTAL_CODE', mapi_prop_tag(PT_TSTRING, 0x3a5b));
    define('PR_HOME_ADDRESS_COUNTRY', mapi_prop_tag(PT_TSTRING, 0x3a5a));
    define('PR_OTHER_ADDRESS_STREET', mapi_prop_tag(PT_TSTRING, 0x3a63));
    define('PR_OTHER_ADDRESS_CITY', mapi_prop_tag(PT_TSTRING, 0x3a5f));
    define('PR_OTHER_ADDRESS_STATE_OR_PROVINCE', mapi_prop_tag(PT_TSTRING, 0x3a62));
    define('PR_OTHER_ADDRESS_POSTAL_CODE', mapi_prop_tag(PT_TSTRING, 0x3a61));
    define('PR_OTHER_ADDRESS_COUNTRY', mapi_prop_tag(PT_TSTRING, 0x3a60));
    define('PR_COUNTRY', mapi_prop_tag(PT_TSTRING, 0x3a26));
    define('PR_LOCALITY', mapi_prop_tag(PT_TSTRING, 0x3a27));
    define('PR_POSTAL_ADDRESS', mapi_prop_tag(PT_TSTRING, 0x3a15));
    define('PR_POSTAL_CODE', mapi_prop_tag(PT_TSTRING, 0x3a2a));
    define('PR_STATE_OR_PROVINCE', mapi_prop_tag(PT_TSTRING, 0x3a28));
    define('PR_STREET_ADDRESS', mapi_prop_tag(PT_TSTRING, 0x3a29));
    define('PR_BODY', mapi_prop_tag(PT_TSTRING, 0x1000));
    define('PR_STORE_SUPPORT_MASK', mapi_prop_tag(PT_LONG, 0x340d));
}
Esempio n. 14
0
 function SendMail($rfc822, $forward = false, $reply = false, $parent = false)
 {
     if (WBXML_DEBUG == true) {
         debugLog("SendMail: forward: {$forward}   reply: {$reply}   parent: {$parent}\n" . $rfc822);
     }
     $mimeParams = array('decode_headers' => true, 'decode_bodies' => true, 'include_bodies' => true, 'charset' => 'utf-8');
     $mimeObject = new Mail_mimeDecode($rfc822);
     $message = $mimeObject->decode($mimeParams);
     // Open the outbox and create the message there
     $storeprops = mapi_getprops($this->_defaultstore, array(PR_IPM_OUTBOX_ENTRYID, PR_IPM_SENTMAIL_ENTRYID));
     if (!isset($storeprops[PR_IPM_OUTBOX_ENTRYID])) {
         debugLog("Outbox not found to create message");
         return false;
     }
     $outbox = mapi_msgstore_openentry($this->_defaultstore, $storeprops[PR_IPM_OUTBOX_ENTRYID]);
     if (!$outbox) {
         debugLog("Unable to open outbox");
         return false;
     }
     $mapimessage = mapi_folder_createmessage($outbox);
     mapi_setprops($mapimessage, array(PR_SUBJECT => u2wi(isset($message->headers["subject"]) ? $message->headers["subject"] : ""), PR_SENTMAIL_ENTRYID => $storeprops[PR_IPM_SENTMAIL_ENTRYID], PR_MESSAGE_CLASS => "IPM.Note", PR_MESSAGE_DELIVERY_TIME => time()));
     if (isset($message->headers["x-priority"])) {
         switch ($message->headers["x-priority"]) {
             case 1:
             case 2:
                 $priority = PRIO_URGENT;
                 $importance = IMPORTANCE_HIGH;
                 break;
             case 4:
             case 5:
                 $priority = PRIO_NONURGENT;
                 $importance = IMPORTANCE_LOW;
                 break;
             case 3:
             default:
                 $priority = PRIO_NORMAL;
                 $importance = IMPORTANCE_NORMAL;
                 break;
         }
         mapi_setprops($mapimessage, array(PR_IMPORTANCE => $importance, PR_PRIORITY => $priority));
     }
     $addresses = array();
     $toaddr = $ccaddr = $bccaddr = array();
     $Mail_RFC822 = new Mail_RFC822();
     if (isset($message->headers["to"])) {
         $toaddr = $Mail_RFC822->parseAddressList($message->headers["to"]);
     }
     if (isset($message->headers["cc"])) {
         $ccaddr = $Mail_RFC822->parseAddressList($message->headers["cc"]);
     }
     if (isset($message->headers["bcc"])) {
         $bccaddr = $Mail_RFC822->parseAddressList($message->headers["bcc"]);
     }
     // Add recipients
     $recips = array();
     if (isset($toaddr)) {
         foreach (array(MAPI_TO => $toaddr, MAPI_CC => $ccaddr, MAPI_BCC => $bccaddr) as $type => $addrlist) {
             foreach ($addrlist as $addr) {
                 $mapirecip[PR_ADDRTYPE] = "SMTP";
                 $mapirecip[PR_EMAIL_ADDRESS] = $addr->mailbox . "@" . $addr->host;
                 if (isset($addr->personal) && strlen($addr->personal) > 0) {
                     $mapirecip[PR_DISPLAY_NAME] = u2wi($addr->personal);
                 } else {
                     $mapirecip[PR_DISPLAY_NAME] = $mapirecip[PR_EMAIL_ADDRESS];
                 }
                 $mapirecip[PR_RECIPIENT_TYPE] = $type;
                 $mapirecip[PR_ENTRYID] = mapi_createoneoff($mapirecip[PR_DISPLAY_NAME], $mapirecip[PR_ADDRTYPE], $mapirecip[PR_EMAIL_ADDRESS]);
                 array_push($recips, $mapirecip);
             }
         }
     }
     mapi_message_modifyrecipients($mapimessage, 0, $recips);
     // Loop through message subparts.
     $body = "";
     $body_html = "";
     if ($message->ctype_primary == "multipart" && ($message->ctype_secondary == "mixed" || $message->ctype_secondary == "alternative")) {
         $mparts = $message->parts;
         for ($i = 0; $i < count($mparts); $i++) {
             $part = $mparts[$i];
             // palm pre & iPhone send forwarded messages in another subpart which are also parsed
             if ($part->ctype_primary == "multipart" && ($part->ctype_secondary == "mixed" || $part->ctype_secondary == "alternative" || $part->ctype_secondary == "related")) {
                 foreach ($part->parts as $spart) {
                     $mparts[] = $spart;
                 }
                 continue;
             }
             // standard body
             if ($part->ctype_primary == "text" && $part->ctype_secondary == "plain" && isset($part->body) && (!isset($part->disposition) || $part->disposition != "attachment")) {
                 $body .= u2wi($part->body);
                 // assume only one text body
             } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "html") {
                 $body_html .= u2wi($part->body);
             } elseif ($part->ctype_primary == "ms-tnef" || $part->ctype_secondary == "ms-tnef") {
                 $zptnef = new ZPush_tnef($this->_defaultstore);
                 $mapiprops = array();
                 $zptnef->extractProps($part->body, $mapiprops);
                 if (is_array($mapiprops) && !empty($mapiprops)) {
                     //check if it is a recurring item
                     $tnefrecurr = GetPropIDFromString($this->_defaultstore, "PT_BOOLEAN:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x5");
                     if (isset($mapiprops[$tnefrecurr])) {
                         $this->_handleRecurringItem($mapimessage, $mapiprops);
                     }
                     mapi_setprops($mapimessage, $mapiprops);
                 } else {
                     debugLog("TNEF: Mapi props array was empty");
                 }
             } elseif ($part->ctype_primary == "text" && $part->ctype_secondary == "calendar") {
                 $zpical = new ZPush_ical($this->_defaultstore);
                 $mapiprops = array();
                 $zpical->extractProps($part->body, $mapiprops);
                 // iPhone sends a second ICS which we ignore if we can
                 if (!isset($mapiprops[PR_MESSAGE_CLASS]) && strlen(trim($body)) == 0) {
                     debugLog("Secondary iPhone response is being ignored!! Mail dropped!");
                     return true;
                 }
                 if (!checkMapiExtVersion("6.30") && is_array($mapiprops) && !empty($mapiprops)) {
                     mapi_setprops($mapimessage, $mapiprops);
                 } else {
                     // store ics as attachment
                     //see icalTimezoneFix function in compat.php for more information
                     $part->body = icalTimezoneFix($part->body);
                     $this->_storeAttachment($mapimessage, $part);
                     debugLog("Sending ICS file as attachment");
                 }
             } else {
                 $this->_storeAttachment($mapimessage, $part);
             }
         }
     } else {
         if ($message->ctype_primary == "text" && $message->ctype_secondary == "html") {
             $body_html .= u2wi($message->body);
         } else {
             $body = u2wi($message->body);
         }
     }
     // some devices only transmit a html body
     if (strlen($body) == 0 && strlen($body_html) > 0) {
         debugLog("only html body sent, transformed into plain text");
         $body = strip_tags($body_html);
     }
     if ($forward) {
         $orig = $forward;
     }
     if ($reply) {
         $orig = $reply;
     }
     if (isset($orig) && $orig) {
         // Append the original text body for reply/forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         if ($fwmessage) {
             //update icon when forwarding or replying message
             if ($forward) {
                 mapi_setprops($fwmessage, array(PR_ICON_INDEX => 262));
             } elseif ($reply) {
                 mapi_setprops($fwmessage, array(PR_ICON_INDEX => 261));
             }
             mapi_savechanges($fwmessage);
             $stream = mapi_openproperty($fwmessage, PR_BODY, IID_IStream, 0, 0);
             $fwbody = "";
             while (1) {
                 $data = mapi_stream_read($stream, 1024);
                 if (strlen($data) == 0) {
                     break;
                 }
                 $fwbody .= $data;
             }
             $stream = mapi_openproperty($fwmessage, PR_HTML, IID_IStream, 0, 0);
             $fwbody_html = "";
             while (1) {
                 $data = mapi_stream_read($stream, 1024);
                 if (strlen($data) == 0) {
                     break;
                 }
                 $fwbody_html .= $data;
             }
             if ($forward) {
                 // During a forward, we have to add the forward header ourselves. This is because
                 // normally the forwarded message is added as an attachment. However, we don't want this
                 // because it would be rather complicated to copy over the entire original message due
                 // to the lack of IMessage::CopyTo ..
                 $fwmessageprops = mapi_getprops($fwmessage, array(PR_SENT_REPRESENTING_NAME, PR_DISPLAY_TO, PR_DISPLAY_CC, PR_SUBJECT, PR_CLIENT_SUBMIT_TIME));
                 $fwheader = "\r\n\r\n";
                 $fwheader .= "-----Original Message-----\r\n";
                 if (isset($fwmessageprops[PR_SENT_REPRESENTING_NAME])) {
                     $fwheader .= "From: " . $fwmessageprops[PR_SENT_REPRESENTING_NAME] . "\r\n";
                 }
                 if (isset($fwmessageprops[PR_DISPLAY_TO]) && strlen($fwmessageprops[PR_DISPLAY_TO]) > 0) {
                     $fwheader .= "To: " . $fwmessageprops[PR_DISPLAY_TO] . "\r\n";
                 }
                 if (isset($fwmessageprops[PR_DISPLAY_CC]) && strlen($fwmessageprops[PR_DISPLAY_CC]) > 0) {
                     $fwheader .= "Cc: " . $fwmessageprops[PR_DISPLAY_CC] . "\r\n";
                 }
                 if (isset($fwmessageprops[PR_CLIENT_SUBMIT_TIME])) {
                     $fwheader .= "Sent: " . strftime("%x %X", $fwmessageprops[PR_CLIENT_SUBMIT_TIME]) . "\r\n";
                 }
                 if (isset($fwmessageprops[PR_SUBJECT])) {
                     $fwheader .= "Subject: " . $fwmessageprops[PR_SUBJECT] . "\r\n";
                 }
                 $fwheader .= "\r\n";
                 // add fwheader to body and body_html
                 $body .= $fwheader;
                 if (strlen($body_html) > 0) {
                     $body_html .= str_ireplace("\r\n", "<br>", $fwheader);
                 }
             }
             if (strlen($body) > 0) {
                 $body .= $fwbody;
             }
             if (strlen($body_html) > 0) {
                 $body_html .= $fwbody_html;
             }
         } else {
             debugLog("Unable to open item with id {$orig} for forward/reply");
         }
     }
     if ($forward) {
         // Add attachments from the original message in a forward
         $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($parent), hex2bin($orig));
         $fwmessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         $attachtable = mapi_message_getattachmenttable($fwmessage);
         $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
         foreach ($rows as $row) {
             if (isset($row[PR_ATTACH_NUM])) {
                 $attach = mapi_message_openattach($fwmessage, $row[PR_ATTACH_NUM]);
                 $newattach = mapi_message_createattach($mapimessage);
                 // Copy all attachments from old to new attachment
                 $attachprops = mapi_getprops($attach);
                 mapi_setprops($newattach, $attachprops);
                 if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) {
                     // Data is in a stream
                     $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN);
                     $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE);
                     while (1) {
                         $data = mapi_stream_read($srcstream, 4096);
                         if (strlen($data) == 0) {
                             break;
                         }
                         mapi_stream_write($dststream, $data);
                     }
                     mapi_stream_commit($dststream);
                 }
                 mapi_savechanges($newattach);
             }
         }
     }
     //set PR_INTERNET_CPID to 65001 (utf-8) if store supports it and to 1252 otherwise
     $internetcpid = 1252;
     if (defined('STORE_SUPPORTS_UNICODE') && STORE_SUPPORTS_UNICODE == true) {
         $internetcpid = 65001;
     }
     mapi_setprops($mapimessage, array(PR_BODY => $body, PR_INTERNET_CPID => $internetcpid));
     if (strlen($body_html) > 0) {
         mapi_setprops($mapimessage, array(PR_HTML => $body_html));
     }
     mapi_savechanges($mapimessage);
     mapi_message_submitmessage($mapimessage);
     return true;
 }
Esempio n. 15
0
 *
 * This software use SabreDAV, an open source software distributed
 * with New BSD License. Please see <http://code.google.com/p/sabredav/>
 * for more information about SabreDAV
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *  
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project page: <http://code.google.com/p/sabre-zarafa/>
 * 
 */
// PHP-MAPI
require_once "mapi/mapi.util.php";
require_once "mapi/mapicode.php";
require_once "mapi/mapidefs.php";
require_once "mapi/mapitags.php";
require_once "mapi/mapiguid.php";
// Add some custom properties to store whatever I need
// Decided to start property IDs to 0xB600 which should not interfere with Zarafa (hope so)
define('CARDDAV_CUSTOM_PROPERTY_ID', 0xb600);
define('PR_CARDDAV_URI', mapi_prop_tag(PT_STRING8, CARDDAV_CUSTOM_PROPERTY_ID | 0x0));
define('PR_CARDDAV_RAW_DATA', mapi_prop_tag(PT_STRING8, CARDDAV_CUSTOM_PROPERTY_ID | 0x1));
define('PR_CARDDAV_RAW_DATA_GENERATION_TIME', mapi_prop_tag(PT_SYSTIME, CARDDAV_CUSTOM_PROPERTY_ID | 0x2));
define('PR_CARDDAV_AB_CONTACT_COUNT', mapi_prop_tag(PT_LONG, CARDDAV_CUSTOM_PROPERTY_ID | 0x3));
define('PR_CARDDAV_RAW_DATA_VERSION', mapi_prop_tag(PT_STRING8, CARDDAV_CUSTOM_PROPERTY_ID | 0x4));
Esempio n. 16
0
 /**
  * Copies attachments from one message to another.
  *
  * @param MAPIMessage $toMessage
  * @param MAPIMessage $fromMessage
  *
  * @return void
  */
 private function copyAttachments(&$toMessage, $fromMessage)
 {
     $attachtable = mapi_message_getattachmenttable($fromMessage);
     $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
     foreach ($rows as $row) {
         if (isset($row[PR_ATTACH_NUM])) {
             $attach = mapi_message_openattach($fromMessage, $row[PR_ATTACH_NUM]);
             $newattach = mapi_message_createattach($toMessage);
             // Copy all attachments from old to new attachment
             $attachprops = mapi_getprops($attach);
             mapi_setprops($newattach, $attachprops);
             if (isset($attachprops[mapi_prop_tag(PT_ERROR, mapi_prop_id(PR_ATTACH_DATA_BIN))])) {
                 // Data is in a stream
                 $srcstream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN);
                 $dststream = mapi_openpropertytostream($newattach, PR_ATTACH_DATA_BIN, MAPI_MODIFY | MAPI_CREATE);
                 while (1) {
                     $data = mapi_stream_read($srcstream, 4096);
                     if (strlen($data) == 0) {
                         break;
                     }
                     mapi_stream_write($dststream, $data);
                 }
                 mapi_stream_commit($dststream);
             }
             mapi_savechanges($newattach);
         }
     }
 }
Esempio n. 17
0
 function readCertsfromContact($emailaddress)
 {
     $email1address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x8083");
     $email2address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x8093");
     $email3address = GetPropIDFromString($this->_defaultstore, "PT_STRING8:{00062004-0000-0000-C000-000000000046}:0x80A3");
     $x509certs = mapi_prop_tag(PT_MV_BINARY, 0x3a70);
     $rows = $this->readResolveRecipientsfromContacts($emailaddress);
     foreach ($rows as $entry) {
         $res['displayname'] = w2u($entry[PR_DISPLAY_NAME]);
         $res['type'] = 2;
         if (isset($entry[$email1address]) && $entry[$email1address] == $emailaddress) {
             $res['emailaddress'] = $entry[$email1address];
         } else {
             if (isset($entry[$email2address]) && $entry[$email2address] == $emailaddress) {
                 $res['emailaddress'] = $entry[$email2address];
             } else {
                 if (isset($entry[$email3address]) && $entry[$email3address] == $emailaddress) {
                     $res['emailaddress'] = $entry[$email3address];
                 }
             }
         }
         $entries = array();
         if (isset($entry[$x509certs]) && USERX509CERTIFICATES == true) {
             $certs = new Userx509Certificates(isset($entry[$x509certs]) ? $entry[$x509certs] : array());
             if ($der_certs = $certs->findCertificatebySubjectValue('emailAddress', $emailaddress)) {
                 foreach ($der_certs as $der_cert) {
                     $entries[] = base64_encode($der_cert);
                 }
             }
         }
         $res['entries'] = $entries;
         if (count($res['entries']) > 0) {
             $result[$emailaddress][] = $res;
         }
     }
     return $result;
 }
Esempio n. 18
0
 /**
  * Returns the error code for a given property. Helper for getNativeBodyType function.
  *
  * @param int               $tag
  * @param array             $messageprops
  *
  * @access private
  * @return int (MAPI_ERROR_CODE)
  */
 private function getError($tag, $messageprops)
 {
     $prBodyError = mapi_prop_tag(PT_ERROR, mapi_prop_id($tag));
     if (isset($messageprops[$prBodyError]) && mapi_is_error($messageprops[$prBodyError])) {
         if ($messageprops[$prBodyError] == MAPI_E_NOT_ENOUGH_MEMORY_32BIT || $messageprops[$prBodyError] == MAPI_E_NOT_ENOUGH_MEMORY_64BIT) {
             return MAPI_E_NOT_ENOUGH_MEMORY;
         }
     }
     return MAPI_E_NOT_FOUND;
 }
Esempio n. 19
0
 function setSettings($request, $devid)
 {
     if (isset($request["oof"])) {
         if ($request["oof"]["oofstate"] == 1) {
             foreach ($request["oof"]["oofmsgs"] as $oofmsg) {
                 switch ($oofmsg["appliesto"]) {
                     case SYNC_SETTINGS_APPLIESTOINTERNAL:
                         $result = mapi_setprops($this->_defaultstore, array(PR_EC_OUTOFOFFICE_MSG => utf8_to_windows1252(isset($oofmsg["replymessage"]) ? $oofmsg["replymessage"] : ""), PR_EC_OUTOFOFFICE_SUBJECT => utf8_to_windows1252(_("Out of office notification"))));
                         break;
                 }
             }
             $response["oof"]["status"] = mapi_setprops($this->_defaultstore, array(PR_EC_OUTOFOFFICE => $request["oof"]["oofstate"] == 1 ? true : false));
         } else {
             $response["oof"]["status"] = mapi_setprops($this->_defaultstore, array(PR_EC_OUTOFOFFICE => $request["oof"]["oofstate"] == 1 ? true : false));
         }
     }
     if (isset($request["deviceinformation"])) {
         if ($this->_defaultstore !== false) {
             //get devices settings from store
             $props = array();
             $props[SYNC_SETTINGS_MODEL] = mapi_prop_tag(PT_MV_STRING8, 0x6890);
             $props[SYNC_SETTINGS_IMEI] = mapi_prop_tag(PT_MV_STRING8, 0x6891);
             $props[SYNC_SETTINGS_FRIENDLYNAME] = mapi_prop_tag(PT_MV_STRING8, 0x6892);
             $props[SYNC_SETTINGS_OS] = mapi_prop_tag(PT_MV_STRING8, 0x6893);
             $props[SYNC_SETTINGS_OSLANGUAGE] = mapi_prop_tag(PT_MV_STRING8, 0x6894);
             $props[SYNC_SETTINGS_PHONENUMBER] = mapi_prop_tag(PT_MV_STRING8, 0x6895);
             $props[SYNC_SETTINGS_USERAGENT] = mapi_prop_tag(PT_MV_STRING8, 0x6896);
             $props[SYNC_SETTINGS_ENABLEOUTBOUNDSMS] = mapi_prop_tag(PT_MV_STRING8, 0x6897);
             $props[SYNC_SETTINGS_MOBILEOPERATOR] = mapi_prop_tag(PT_MV_STRING8, 0x6898);
             $sprops = mapi_getprops($this->_defaultstore, array(0x6881101e, $props[SYNC_SETTINGS_MODEL], $props[SYNC_SETTINGS_IMEI], $props[SYNC_SETTINGS_FRIENDLYNAME], $props[SYNC_SETTINGS_OS], $props[SYNC_SETTINGS_OSLANGUAGE], $props[SYNC_SETTINGS_PHONENUMBER], $props[SYNC_SETTINGS_USERAGENT], $props[SYNC_SETTINGS_ENABLEOUTBOUNDSMS], $props[SYNC_SETTINGS_MOBILEOPERATOR]));
             //try to find index of current device
             $ak = array_search($devid, $sprops[0x6881101e]);
             // Set undefined properties to the amount of known device ids
             foreach ($props as $key => $value) {
                 if (!isset($sprops[$value])) {
                     for ($i = 0; $i < sizeof($sprops[0x6881101e]); $i++) {
                         $sprops[$value][] = "undefined";
                     }
                 }
             }
             if ($ak !== false) {
                 //update settings (huh this could really occur?!?! - maybe in case of OS update)
                 foreach ($request["deviceinformation"] as $key => $value) {
                     if (trim($value) != "") {
                         $sprops[$props[$key]][$ak] = $value;
                     } else {
                         $sprops[$props[$key]][$ak] = "undefined";
                     }
                 }
             } else {
                 //new device settings for the db
                 $devicesprops[0x6881101e][] = $devid;
                 foreach ($props as $key => $value) {
                     if (isset($request["deviceinformation"][$key]) && trim($request["deviceinformation"][$key]) != "") {
                         $sprops[$value][] = $request["deviceinformation"][$key];
                     } else {
                         $sprops[$value][] = "undefined";
                     }
                 }
             }
             // save them
             $response["deviceinformation"]["status"] = mapi_setprops($this->_defaultstore, $sprops);
         }
     }
     if (isset($request["devicepassword"])) {
         if ($this->_defaultstore !== false) {
             //get devices settings from store
             $props = array();
             $props[SYNC_SETTINGS_PASSWORD] = mapi_prop_tag(PT_MV_STRING8, 0x689f);
             $pprops = mapi_getprops($this->_defaultstore, array(0x6881101e, $props[SYNC_SETTINGS_PASSWORD]));
             //try to find index of current device
             $ak = array_search($devid, $pprops[0x6881101e]);
             // Set undefined properties to the amount of known device ids
             foreach ($props as $key => $value) {
                 if (!isset($pprops[$value])) {
                     for ($i = 0; $i < sizeof($pprops[0x6881101e]); $i++) {
                         $pprops[$value][] = "undefined";
                     }
                 }
             }
             if ($ak !== false) {
                 //update password
                 if (trim($value) != "") {
                     $pprops[$props[$key]][$ak] = $request["devicepassword"];
                 } else {
                     $pprops[$props[$key]][$ak] = "undefined";
                 }
             } else {
                 //new device password for the db
                 $devicesprops[0x6881101e][] = $devid;
                 foreach ($props as $key => $value) {
                     if (isset($request["devicepassword"]) && trim($request["devicepassword"]) != "") {
                         $pprops[$value][] = $request["devicepassword"];
                     } else {
                         $pprops[$value][] = "undefined";
                     }
                 }
             }
             // save them
             $response["devicepassword"]["status"] = mapi_setprops($this->_defaultstore, $pprops);
         }
     }
     return $response;
 }