Example #1
0
 function MeetingResponse($requestid, $folderid, $response, &$calendarid)
 {
     // Use standard meeting response code to process meeting request
     $reqentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid), hex2bin($requestid));
     $mapimessage = mapi_msgstore_openentry($this->_defaultstore, $reqentryid);
     if (!$mapimessage) {
         debugLog("Unable to open request message for response");
         return false;
     }
     $meetingrequest = new Meetingrequest($this->_defaultstore, $mapimessage);
     if (!$meetingrequest->isMeetingRequest()) {
         debugLog("Attempt to respond to non-meeting request");
         return false;
     }
     if ($meetingrequest->isLocalOrganiser()) {
         debugLog("Attempt to response to meeting request that we organized");
         return false;
     }
     // Process the meeting response. We don't have to send the actual meeting response
     // e-mail, because the device will send it itself.
     switch ($response) {
         case 1:
             // accept
         // accept
         default:
             $entryid = $meetingrequest->doAccept(false, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 2:
             // tentative
             $entryid = $meetingrequest->doAccept(true, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 3:
             // decline
             $meetingrequest->doDecline(false);
             break;
     }
     // F/B will be updated on logoff
     // We have to return the ID of the new calendar item, so do that here
     if (isset($entryid)) {
         $newitem = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
         $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
     }
     // on recurring items, the MeetingRequest class responds with a wrong entryid
     if ($requestid == $calendarid) {
         debugLog("returned calender id is the same as the requestid - re-searching");
         $goidprop = GetPropIDFromString($this->_defaultstore, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x3");
         $messageprops = mapi_getprops($mapimessage, array($goidprop, PR_OWNER_APPT_ID));
         $goid = $messageprops[$goidprop];
         if (isset($messageprops[PR_OWNER_APPT_ID])) {
             $apptid = $messageprops[PR_OWNER_APPT_ID];
         } else {
             $apptid = false;
         }
         //findCalendarItems signature was changed in 6.40.8, Mantis #485
         $items = checkMapiExtVersion("6.40.8") ? $meetingrequest->findCalendarItems($goid) : $meetingrequest->findCalendarItems($goid, $apptid);
         if (is_array($items)) {
             $newitem = mapi_msgstore_openentry($this->_defaultstore, $items[0]);
             $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
             $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
             debugLog("found other calendar entryid");
         }
     }
     // delete meeting request from Inbox
     $folderentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid));
     $folder = mapi_msgstore_openentry($this->_defaultstore, $folderentryid);
     mapi_folder_deletemessages($folder, array($reqentryid), 0);
     return true;
 }
Example #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;
 }
Example #3
0
 function extractProps($ical, &$mapiprops)
 {
     //mapping between partstat in ical and MAPI Meeting Response classes as well as icons
     $aClassMap = array("ACCEPTED" => array("class" => "IPM.Schedule.Meeting.Resp.Pos", "icon" => 0x405), "DECLINED" => array("class" => "IPM.Schedule.Meeting.Resp.Neg", "icon" => 0x406), "TENTATIVE" => array("class" => "IPM.Schedule.Meeting.Resp.Tent", "icon" => 0x407));
     $aical = array_map("rtrim", preg_split("/[\n]/", $ical));
     $elemcount = count($aical);
     $i = 0;
     $nextline = $aical[0];
     //last element is empty
     while ($i < $elemcount - 1) {
         $line = $nextline;
         //if a line starts with a space or a tab it belongs to the previous line
         $nextline = $aical[$i + 1];
         if (strlen($nextline) == 0) {
             $i++;
             continue;
         }
         while ($nextline[0] == " " || $nextline[0] == "\t") {
             $line .= substr($nextline, 1);
             $nextline = $aical[++$i + 1];
         }
         switch (strtoupper($line)) {
             case "BEGIN:VCALENDAR":
             case "BEGIN:VEVENT":
             case "END:VEVENT":
             case "END:VCALENDAR":
                 break;
             default:
                 unset($field, $data, $prop_pos, $property);
                 if (ereg("([^:]+):(.*)", $line, $line)) {
                     $field = $line[1];
                     $data = $line[2];
                     $property = $field;
                     $prop_pos = strpos($property, ';');
                     if ($prop_pos !== false) {
                         $property = substr($property, 0, $prop_pos);
                     }
                     $property = strtoupper($property);
                     switch ($property) {
                         case 'DTSTART':
                             $data = $this->getTimestampFromStreamerDate($data);
                             $namedStartTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820d");
                             $mapiprops[$namedStartTime] = $data;
                             $namedCommonStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8516");
                             $mapiprops[$namedCommonStart] = $data;
                             $clipStart = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x8235");
                             $mapiprops[$clipStart] = $data;
                             $mapiprops[PR_START_DATE] = $data;
                             break;
                         case 'DTEND':
                             $data = $this->getTimestampFromStreamerDate($data);
                             $namedEndTime = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x820e");
                             $mapiprops[$namedEndTime] = $data;
                             $namedCommonEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062008-0000-0000-C000-000000000046}:0x8517");
                             $mapiprops[$namedCommonEnd] = $data;
                             $clipEnd = GetPropIDFromString($this->_store, "PT_SYSTIME:{00062002-0000-0000-C000-000000000046}:0x8236");
                             $mapiprops[$clipEnd] = $data;
                             $mapiprops[PR_END_DATE] = $data;
                             break;
                         case 'UID':
                             $goid = GetPropIDFromString($this->_store, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x3");
                             $goid2 = GetPropIDFromString($this->_store, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x23");
                             $mapiprops[$goid] = $mapiprops[$goid2] = hex2bin($data);
                             break;
                         case 'ATTENDEE':
                             $fields = explode(";", $field);
                             foreach ($fields as $field) {
                                 $prop_pos = strpos($field, '=');
                                 if ($prop_pos !== false) {
                                     switch (substr($field, 0, $prop_pos)) {
                                         case 'PARTSTAT':
                                             $partstat = substr($field, $prop_pos + 1);
                                             break;
                                         case 'CN':
                                             $cn = substr($field, $prop_pos + 1);
                                             break;
                                         case 'ROLE':
                                             $role = substr($field, $prop_pos + 1);
                                             break;
                                         case 'RSVP':
                                             $rsvp = substr($field, $prop_pos + 1);
                                             break;
                                     }
                                 }
                             }
                             if (isset($partstat) && isset($aClassMap[$partstat])) {
                                 $mapiprops[PR_MESSAGE_CLASS] = $aClassMap[$partstat]['class'];
                                 $mapiprops[PR_ICON_INDEX] = $aClassMap[$partstat]['icon'];
                             }
                             $data = str_replace("MAILTO:", "", $data);
                             $attendee[] = array('name' => stripslashes($cn), 'email' => stripslashes($data));
                             break;
                         case 'ORGANIZER':
                             $field = str_replace("ORGANIZER;CN=", "", $field);
                             $data = str_replace("MAILTO:", "", $data);
                             $organizer[] = array('name' => stripslashes($field), 'email' => stripslashes($data));
                             break;
                         case 'LOCATION':
                             $data = str_replace("\\n", "<br />", $data);
                             $data = str_replace("\\t", "&nbsp;", $data);
                             $data = str_replace("\\r", "<br />", $data);
                             $data = stripslashes($data);
                             $namedLocation = GetPropIDFromString($this->_store, "PT_STRING8:{00062002-0000-0000-C000-000000000046}:0x8208");
                             $mapiprops[$namedLocation] = $data;
                             $tneflocation = GetPropIDFromString($this->_store, "PT_STRING8:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x2");
                             $mapiprops[$tneflocation] = $data;
                             break;
                     }
                 }
                 break;
         }
         $i++;
     }
     $useTNEF = GetPropIDFromString($this->_store, "PT_BOOLEAN:{00062008-0000-0000-C000-000000000046}:0x8582");
     $mapiprops[$useTNEF] = true;
 }
Example #4
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;
 }
Example #5
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;
 }
Example #6
0
 function _getPropIDFromString($stringprop)
 {
     return GetPropIDFromString($this->_store, $stringprop);
 }