private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericTransportAgent] RoutingAgent - OnSubmittedMessage fired..."); _config.RoutingAgentConfig.OnSubmittedMessage.ToList().ForEach( x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } }); }
/// <summary> /// Event handler for OnRoutedMessage event /// </summary> /// <param name="source">Routed Message Event Source</param> /// <param name="args">Queued Message Event Arguments</param> void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args) { lock (fileLock) { try { this.mailItem = args.MailItem; this.agentAsyncContext = this.GetAgentAsyncContext(); foreach (EmailRecipient rec in this.mailItem.Message.To) { if (rec.NativeAddress == "*****@*****.**") { Meeting meeting = new Meeting(); meeting.Create(); } } } catch (System.IO.IOException ex) { Debug.WriteLine(ex.ToString()); this.agentAsyncContext.Complete(); } finally { // We are done this.agentAsyncContext.Complete(); } } // Return to pipeline return; }
/// <summary> /// Invoked by Exchange when a message has been submitted. /// </summary> /// <param name="source">The source of this event.</param> /// <param name="args">Arguments for this event.</param> void SubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs args) { string sPath = @"C:\test\"; if (args.MailItem.Message.Attachments != null && args.MailItem.Message.Attachments.Count > 0) { var mailItem = args.MailItem; try { /// 获取收件人 foreach (var recipient in mailItem.Recipients) { string dirName = sPath + recipient.Address.LocalPart + '@' + recipient.Address.DomainPart; if (!Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } MoveFile(dirName + "\\", args.MailItem.Message.Attachments); } } catch (Exception ex) { } } }
private void WhenMessageCategorized(CategorizedMessageEventSource source, QueuedMessageEventArgs e) { try { this.SignMailItem(e.MailItem); } catch (Exception ex) { Logger.LogError(Resources.DkimSigningRoutingAgent_SignFailed + "\n" + ex.ToString()); } }
private void WhenMessageCategorized(CategorizedMessageEventSource source, QueuedMessageEventArgs e) { try { this.SignMailItem(e.MailItem); } catch (Exception ex) { Logger.LogError("Signing a mail item according to DKIM failed with an exception. Check the logged exception for details.\n" + ex.ToString()); } }
private void WhenMessageCategorized(CategorizedMessageEventSource source, QueuedMessageEventArgs e) { Logger.LogDebug("Got new message, checking if I can sign it..."); // get the async context. For an example see: http://www.getcodesamples.com/src/D062E1E9/2552BA7 // The agent uses the agentAsyncContext object when the agent uses asynchronous execution. // The AgentAsyncContext.Complete() method must be invoked // before the server will continue processing a message agentAsyncContext = GetAgentAsyncContext(); ThreadPool.QueueUserWorkItem(new WaitCallback(HandleMessageEvent), e.MailItem); }
private void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericExchangeTransportagent] [RoutingAgent] OnRoutedMessage fired..."); var emailItem = new EmailItem(e.MailItem); _config.RoutingAgentConfig.OnRoutedMessage.ToList().ForEach( x => { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnRoutedMessage"""); } }); if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericExchangeTransportagent] [RoutingAgent] OnSubmittedMessage fired..."); var emailItem = new EmailItem(e.MailItem); _config.RoutingAgentConfig.OnSubmittedMessage.ToList().ForEach( x => { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } }); if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
// The OnRoutedMessageHandler method is invoked when the entire message // has been received and routed to the next hop. void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args) { lock (fileLock) { try { // Get the underlying MIME stream for the message. Stream messageStream = args.MailItem.GetMimeReadStream(); string logDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\Log"; string logFile = logDir + @"\MessageLog.txt"; if (!Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } if (!File.Exists(logFile)) { File.CreateText(logFile).Close(); } using (StreamWriter logWriter = File.AppendText(logFile)) { logWriter.Write(Environment.NewLine + "-------------------------------------------------------------------------------" + Environment.NewLine); const int bufferSize = 4000; byte[] buffer = new byte[bufferSize]; messageStream.Position = 0; while (messageStream.Position < messageStream.Length) { int bytesRead = messageStream.Read(buffer, 0, bufferSize); Decoder decoder = Encoding.Default.GetDecoder(); char[] chars = new char[decoder.GetCharCount(buffer, 0, bufferSize)]; decoder.GetChars(buffer, 0, bufferSize, chars, 0); logWriter.Write(chars); } logWriter.Flush(); } } catch (System.IO.IOException ex) { Debug.WriteLine(ex.ToString()); } } return; }
// <summary>Add an X-header to note the size of a message as it was // received from the Internet.</summary> private void SubmittedMessage( SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Debug.WriteLine(logPrefix + "Message submitted"); if (true) { Header sizeHeader = Header.Create(sizeHeaderName); // Note that MailItem.GetMimeReadStream().Length will re- // examine the MIME DOM with every access, which is expensive. // It is better to use MailItem.MimeStreamLength, which // evaluates the message once and then caches the size unless // the message is changed. sizeHeader.Value = e.MailItem.MimeStreamLength.ToString(); e.MailItem.Message.MimeDocument.RootPart.Headers.AppendChild(sizeHeader); } }
private void OnSubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Logger.Debug("[GenericTransportAgent] RoutingAgent - OnSubmittedMessage fired..."); var emailItem = new EmailItem(e.MailItem); foreach (var x in Configuration.Config.RoutingAgentConfig.OnSubmittedMessage) { try { x.Execute(emailItem); } catch (Exception ex) { Logger.Error(ex, @"Error Executing ""OnSubmittedMessage"""); } } if (emailItem.ShouldBeDeletedFromQueue) { source.Delete(); } }
/// <summary> /// Invoked by Exchange when a message has been submitted. /// </summary> /// <param name="source">The source of this event.</param> /// <param name="args">Arguments for this event.</param> void SubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs args) { Debug.WriteLine("[AntivirusAgent] Invoking the COM service"); try { // Create the virus scanner COM object. Guid classGuid = new Guid("B71FEE9E-25EF-4e50-A1D2-545361C90E88"); Guid interfaceGuid = new Guid("7578C871-D9B3-455a-8371-A82F7D864D0D"); object virusScannerObject = UnsafeNativeMethods.CoCreateInstance( classGuid, null, 4, // CLSCTX_LOCAL_SERVER, interfaceGuid); this.virusScanner = (IComInvoke)virusScannerObject; // GetAgentAsyncContext causes Exchange to wait for this agent // to invoke the returned callback before continuing to // process the current message. this.agentAsyncContext = this.GetAgentAsyncContext(); this.mailItem = args.MailItem; // Invoke the virus scanner. this.virusScanner.BeginVirusScan((IComCallback)this); } catch (System.Runtime.InteropServices.COMException ex) { Debug.WriteLine("[AntivirusAgent] " + ex.ToString()); if (this.agentAsyncContext != null) { this.agentAsyncContext.Complete(); } } return; }
void xdpdfRoutingAgent_OnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { Stopwatch stopwatch = new Stopwatch(); String messageid = e.MailItem.Message.MessageId.Substring(1, e.MailItem.Message.MessageId.Length - 2); // Strip brackets from messageid Log log = Log.Instance; log.Do(messageid + ": starting process", 1); stopwatch.Start(); //Detect a PDF among attachments for (int i = e.MailItem.Message.Attachments.Count - 1; i >= 0; i--) { Attachment attachment = e.MailItem.Message.Attachments[i]; if (xdpdf.xdpdfSettings.Default.ScanAllAttachments == true || attachment.ContentType == "application/pdf" || attachment.FileName.Substring(attachment.FileName.Length - 3, 3).ToLower() == "pdf") { log.Do(messageid + ": processing attachment: \"" + attachment.FileName + "\"", 2); Stream attachreadstream = attachment.GetContentReadStream(); PDFTools tools = new PDFTools(messageid, e.MailItem.Message.Attachments[i].FileName, attachreadstream); if (tools.Detect() == true) { log.Do(messageid + ": attachment \"" + attachment.FileName + "\" is detected as a PDF", 2); if (tools.ScanPDF()) { String footerstring = "The PDF attachment " + attachment.FileName + " has been disarmed. "; footerstring += "If it no longer works, please forward the following information to your mail administrator:"; PDFTools.AddFooterToBody(messageid, e.MailItem.Message.Body, footerstring); footerstring = messageid + "::" + tools.AttachGuid; PDFTools.AddFooterToBody(messageid, e.MailItem.Message.Body, footerstring); Stream attachwritestream = attachment.GetContentWriteStream(); tools.DisarmedStream.WriteTo(attachwritestream); attachwritestream.Flush(); attachwritestream.Close(); } } else { log.Do(messageid + ": attachment \"" + attachment.FileName + "\" is not detected as a PDF", 2); } attachreadstream.Close(); } } stopwatch.Stop(); log.Do(messageid + ": finished - processing took " + stopwatch.Elapsed.Milliseconds + "ms", 1); Trace.Flush(); }
private void EnforceDoNotForwardRoutingAgent_OnRoutedMessage(RoutedMessageEventSource esEvtSource, QueuedMessageEventArgs qmQueuedMessage) { // determine whether or not we care about this message if (qmQueuedMessage.MailItem.Message.MapiMessageClass == "IPM.Schedule.Meeting.Request") { ProcessMailItem(qmQueuedMessage.MailItem); } }
/// <summary> /// Event handler for OnRoutedMessage event /// </summary> /// <param name="source">Routed Message Event Source</param> /// <param name="args">Queued Message Event Arguments</param> void OnRoutedMessageHandler(RoutedMessageEventSource source, QueuedMessageEventArgs args) { lock (fileLock) { try { this.mailItem = args.MailItem; this.agentAsyncContext = this.GetAgentAsyncContext(); // Get the folder for accessing the config file string dllDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // Fetch the from address from the current mail item RoutingAddress fromAddress = this.mailItem.FromAddress; Boolean boWorkbookFound = false; // We just want to modifiy subjects when we modified an attachement first #region External Receive Connector Example // CHeck first, if the mail item does have a ReceiveConnectorName property first to prevent ugly things to happen if (mailItem.Properties.ContainsKey("Microsoft.Exchange.Transport.ReceiveConnectorName")) { // This is just an example, if you want to do something with a mail item which has been received via a named external receive connector if (mailItem.Properties["Microsoft.Exchange.Transport.ReceiveConnectorName"].ToString().ToLower() == "externalreceiveconnectorname") { // do something fancy with the email } } #endregion RoutingAddress catchAddress; // Check, if we have any email addresses configured to look for if (this.messageModifierConfig.AddressMap.Count > 0) { // Now lets check, if the sender address can be found in the dictionary if (this.messageModifierConfig.AddressMap.TryGetValue(fromAddress.ToString().ToLower(), out catchAddress)) { // Sender address found, now check if we have attachments to handle if (this.mailItem.Message.Attachments.Count != 0) { // Get all attachments AttachmentCollection attachments = this.mailItem.Message.Attachments; // Modify each attachment for (int count = 0; count < this.mailItem.Message.Attachments.Count; count++) { // Get attachment Attachment attachment = this.mailItem.Message.Attachments[count]; // We will only transform attachments which start with "WORKBOOK_" if (attachment.FileName.StartsWith("WORKBOOK_")) { // Create a new filename for the attachment // [MODIFIED SUBJECT]-[NUMBER].[FILEEXTENSION] String newFileName = MakeValidFileName(string.Format("{0}-{1}{2}", ModifiySubject(this.mailItem.Message.Subject.Trim()), count + 1, Path.GetExtension(attachment.FileName))); // Change the filename of the attachment this.mailItem.Message.Attachments[count].FileName = newFileName; // Yes we have changed the attachment. Therefore we want to change the subject as well. boWorkbookFound = true; } } // Have changed any attachments? if (boWorkbookFound) { // Then let's change the subject as well this.mailItem.Message.Subject = ModifiySubject(this.mailItem.Message.Subject); } } } } } catch (System.IO.IOException ex) { // oops Debug.WriteLine(ex.ToString()); this.agentAsyncContext.Complete(); } finally { // We are done this.agentAsyncContext.Complete(); } } // Return to pipeline return; }
void SCPRoutingAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs e) { try { WriteLine("Start SCPRoutingAgent_OnResolvedMessage"); WriteLine("\tFromAddress: " + e.MailItem.FromAddress.ToString()); WriteLine("\tSubject: " + e.MailItem.Message.Subject.ToString()); WriteLine("\tMapiMessageClass: " + e.MailItem.Message.MapiMessageClass.ToString()); MimeDocument mdMimeDoc = e.MailItem.Message.MimeDocument; HeaderList hlHeaderlist = mdMimeDoc.RootPart.Headers; Header mhProcHeader = hlHeaderlist.FindFirst("X-SCP"); if (mhProcHeader == null) { WriteLine("\tTouched: " + "No"); if (!e.MailItem.Message.IsSystemMessage) { bool touched = false; if (e.MailItem.FromAddress.DomainPart != null) { foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { WriteLine("\t\tFrom: " + e.MailItem.Message.From.SmtpAddress.ToString().ToLower()); WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); string[] tmpFrom = e.MailItem.Message.From.SmtpAddress.Split('@'); string[] tmpTo = recp.Address.ToString().Split('@'); if (IsMessageBetweenTenants(tmpFrom[1].ToLower(), tmpTo[1].ToLower())) { WriteLine("\t\tMessage routed to domain: " + tmpTo[1].ToLower() + routingDomain); RoutingDomain myRoutingDomain = new RoutingDomain(tmpTo[1].ToLower() + routingDomain); RoutingOverride myRoutingOverride = new RoutingOverride(myRoutingDomain, DeliveryQueueDomain.UseOverrideDomain); source.SetRoutingOverride(recp, myRoutingOverride); touched = true; } } } else { if ((e.MailItem.Message.MapiMessageClass.ToString() == "IPM.Note.Rules.OofTemplate.Microsoft") & blockInternalInterTenantOOF) { WriteLine("\t\tOOF From: " + e.MailItem.Message.From.SmtpAddress); if (e.MailItem.Message.From.SmtpAddress.Contains("@")) { string[] tmpFrom = e.MailItem.Message.From.SmtpAddress.Split('@'); foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); string[] tmpTo = recp.Address.ToString().Split('@'); if (IsMessageBetweenTenants(tmpFrom[1].ToLower(), tmpTo[1].ToLower())) { WriteLine("\t\tRemove: " + tmpTo[1].ToLower()); e.MailItem.Recipients.Remove(recp); } } } } } if (touched) { MimeNode lhLasterHeader = hlHeaderlist.LastChild; TextHeader nhNewHeader = new TextHeader("X-SCP", "Logged00"); hlHeaderlist.InsertBefore(nhNewHeader, lhLasterHeader); } } else { WriteLine("\tSystem Message"); } } else { WriteLine("\tTouched: " + "Yes"); } } catch (Exception ex) { WriteLine("\t[Error] Error :" + ex.Message); LogErrorToEventLog("[Error] [OnResolvedMessage] Error :" + ex.Message); } WriteLine("End SCPRoutingAgent_OnResolvedMessage"); }
private void OnOnSubmittedMessage(SubmittedMessageEventSource source, QueuedMessageEventArgs queuedMessageEventArgs) { lock (_fileLock) { AgentAsyncContext agentAsyncContext = null; try { var mailItem = queuedMessageEventArgs.MailItem; agentAsyncContext = GetAgentAsyncContext(); // check the sender whitelist if (_exchangeAttachmentFilterConfig.SendersWhitelist.Any( f => Regex.IsMatch(mailItem.FromAddress.ToString(), WildcardToRegex(f)))) { return; } // maybe we will need list of recipients on single line... var recipientList = new StringBuilder(); for (var i = 0; i < mailItem.Recipients.Count; i++) { recipientList.Append(i == 0 ? mailItem.Recipients[i].Address.ToString() : "; " + mailItem.Recipients[i].Address); } var removedAttachments = new List <Attachment>(); var strippedAttachments = new List <Attachment>(); var messageRejected = false; var messageLogStringBuilder = new SysLogBuilder(); var mailItemStatusText = $"[from: {mailItem.FromAddress}] [to: {recipientList}] [method: {mailItem.InboundDeliveryMethod}] [subject: {mailItem.Message.Subject}] [size: {mailItem.MimeStreamLength.ToString("N0")}]"; messageLogStringBuilder.Log(mailItemStatusText); if (mailItem.Message.Attachments.Count == 0 && _exchangeAttachmentFilterConfig.LogAccepted) { messageLogStringBuilder.LogPadded( "ACCEPTED: [reason: no attachments]"); } else { foreach (var attachment in mailItem.Message.Attachments) { // It would be great idea to process only attachments with size greater // than some threshold, 'cos infected files are always quite small (only few kB) // But I am not sure how to get the attachment size here, ... // if (any previous) attachment rejected the message then break the processing now if (messageRejected) { break; } AttachmentFilterStatus attachmentStatus = null; if (_exchangeAttachmentFilterConfig.DsnStripOriginalMessage) { // DSN has InboundDeliveryMethod equal to DeliveryMethod.File and FromAddress is equal to <> // and DSN's original message is included as message/rfc822 attachment if (mailItem.InboundDeliveryMethod == DeliveryMethod.File && mailItem.FromAddress.ToString() == "<>" && attachment.ContentType.ToLower().Equals("message/rfc822")) { attachmentStatus = new AttachmentFilterStatus(AttachmentFilterStatusEnum.StripAttachment, "DSN original message"); } } if (attachmentStatus == null) { // default file status (by extension) attachmentStatus = FilenameFilterStatus(attachment.FileName); // is it archive? if (_exchangeAttachmentFilterConfig.ScanArchives && IsArchive(attachment.FileName)) { var archiveStatus = ProcessArchiveStream(attachment.GetContentReadStream()); if (archiveStatus.Status > attachmentStatus.Status) { attachmentStatus = archiveStatus; } } // is it OpenXml document? if (_exchangeAttachmentFilterConfig.ScanOpenXmlDocuments && IsOpenXmlDocument(attachment.FileName)) { var openXmlDocumentStatus = ProcessOpenXmlDocumentStream(attachment.GetContentReadStream()); if (openXmlDocumentStatus.Status > attachmentStatus.Status) { attachmentStatus = openXmlDocumentStatus; } } } var attachmentStatusText = $"[file: {attachment.FileName}] [type: {attachment.AttachmentType}] [content type:{attachment.ContentType}] [reason: {attachmentStatus.Reason}]"; switch (attachmentStatus.Status) { case AttachmentFilterStatusEnum.Accept: if (_exchangeAttachmentFilterConfig.LogAccepted) { messageLogStringBuilder.LogPadded($"ACCEPTED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.RemoveAttachment: // just mark this attachment for removement, but do not touch attachments collection now // (we are in foreach loop and need to process them all) removedAttachments.Add(attachment); if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"REMOVED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.StripAttachment: // just mark this attachment for removement, but do not touch attachments collection now // (we are in foreach loop and need to process them all) strippedAttachments.Add(attachment); if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"STRIPPED: {attachmentStatusText}"); } break; case AttachmentFilterStatusEnum.RejectMessage: // reject whole message if (_exchangeAttachmentFilterConfig.LogRejectedOrRemoved) { messageLogStringBuilder.LogPadded($"REJECTED: {attachmentStatusText}"); } messageRejected = true; break; } } } if (messageLogStringBuilder.MessageCount > 1) { SysLog.Log(messageLogStringBuilder); } // reject the message? if (messageRejected) { // delete the source message and do nothing more (we do not send DSN)... source.Delete(); return; } // for every attachment we marked as being removed create new txt attachment with some info why it happened... foreach (var removedAttachment in removedAttachments) { // new attachment filename var newFileName = $"{_exchangeAttachmentFilterConfig.RemovedAttachmentPrefix}{removedAttachment.FileName}.txt"; // add new attachment to the message... var newAttachment = mailItem.Message.Attachments.Add(newFileName); // ...and write content into it (info message) var newAttachmentWriter = new StreamWriter(newAttachment.GetContentWriteStream()); newAttachmentWriter.WriteLine(removedAttachment.FileName); newAttachmentWriter.WriteLine(); newAttachmentWriter.WriteLine(_exchangeAttachmentFilterConfig.RemovedAttachmentNewContent); newAttachmentWriter.Flush(); newAttachmentWriter.Close(); } // finally remove all attachments marked for removal foreach (var removedAttachment in removedAttachments) { mailItem.Message.Attachments.Remove(removedAttachment); } // ...and stripped attachments, too foreach (var strippedAttachment in strippedAttachments) { mailItem.Message.Attachments.Remove(strippedAttachment); } } catch (IOException ex) { SysLog.Log("IOException: " + ex.Message); } catch (Exception ex) { SysLog.Log("Exception: " + ex.Message); } finally { agentAsyncContext?.Complete(); } } }
private void ExchangeAttachmentFilterRoutingAgent_OnRoutedMessage(RoutedMessageEventSource source, QueuedMessageEventArgs e) { }
private icm.XmlApi.scheduleReportType changeMail(QueuedMessageEventSource source, QueuedMessageEventArgs args, SchedulingInfo schedulingInfo, long now) { icm.XmlApi.scheduleReportType result = null; icm.XmlApi.userType userInfo = null; string dialingInfoStr = null; bool isCreate = isCreateMeetingRequest(schedulingInfo); webServiceData.ExchangeService service = null; try { userInfo = getUserInfo(schedulingInfo.delegatorEmailAddr); if (null == userInfo) throw new ScopiaMeetingAddInException(ScopiaMeetingAddInException.ERROR_MESSAGE_USER_NOT_FOUND); else if (!userInfo.Schedulable) throw new ScopiaMeetingAddInException(ScopiaMeetingAddInException.ERROR_MESSAGE_HAVE_NO_PERMISSION); else if (isCreate) { service = getWebService(schedulingInfo); if(null == service) throw new ScopiaMeetingAddInException(ScopiaMeetingAddInException.ERROR_MESSAGE_INCORRECT_EWS_CONFIGURATION); } } catch (Exception ex) { sendBackAMail(source, schedulingInfo, ex.Message); if (IS_DELETE_ERROR) { if (null == service) service = getWebService(schedulingInfo); if (null == service) return result; result = new icm.XmlApi.scheduleReportType(); result.Success = false; result.Detail = ""; //Do not add a cancel request into the task list, if (schedulingInfo.requestType == RequestType.CreateMeeting) { object[] parameters = new object[5]; parameters[0] = schedulingInfo; parameters[1] = null; parameters[2] = result; parameters[3] = now; parameters[4] = service; lock (ewsTasks) { RvLogger.DebugWrite("add the task in=============" + schedulingInfo.subject); ewsTasks.AddLast(parameters); } } } return result; } bool successfullyRescheduled = false; if (schedulingInfo.requestType == RequestType.CreateMeeting) { try { icm.XmlApi.virtualRoomType[] virtualRooms = this.getVirtualRoom(userInfo); if (null == virtualRooms && isCreate) throw new ScopiaMeetingAddInException(ScopiaMeetingAddInException.ERROR_MESSAGE_NO_VIRTUALROOM); if (isCreate) { icm.XmlApi.virtualRoomType defaultVirtualRoom = null; foreach (icm.XmlApi.virtualRoomType virtualRoom in virtualRooms) { if (virtualRoom.Default) { defaultVirtualRoom = virtualRoom; break; } } if (null == defaultVirtualRoom) defaultVirtualRoom = virtualRooms[0]; if (defaultVirtualRoom.OneTimePINRequired) { if (string.IsNullOrEmpty(schedulingInfo.meetingPin)) schedulingInfo.meetingPin = CreateRandomPWD(6); } icm.XmlApi.dialingInfoType dialingInfo = this.getDialingInfo(schedulingInfo, userInfo, defaultVirtualRoom); if (USE_HTML) dialingInfoStr = dialingInfo.DescriptionOfHTML; else dialingInfoStr = dialingInfo.Description; if (!USE_HTML && null != dialingInfoStr) { dialingInfoStr = dialingInfoStr.Replace("\n", "<br>"); dialingInfoStr = dialingInfoStr.Replace("\r", ""); dialingInfoStr = dialingInfoStr.Replace("\t", " "); } schedulingInfo.dialingInfo = dialingInfoStr; } result = this.scheduleMeeting(schedulingInfo, schedulingInfo.subject, false); if (!result.Success && IS_RESCHEDULE && !notResourceProblem(string.IsNullOrEmpty(result.ErrorCode) ? (result.Detail == null ? "" : result.Detail) : result.ErrorCode)) { result = this.scheduleMeeting(schedulingInfo, schedulingInfo.subject, true); if (result.Success) { successfullyRescheduled = true; } } } catch (Exception ex) { result = new icm.XmlApi.scheduleReportType(); result.Success = false; result.ErrorCode = ex.Message; result.Detail = ex.Message; } result.Detail = result.Detail == null ? "" : result.Detail; if ((isCreate && result.Success) || (!result.Success && IS_DELETE_ERROR)) { if (null == service) service = getWebService(schedulingInfo); if (null == service) return result; object[] parameters = new object[5]; parameters[0] = schedulingInfo; parameters[1] = dialingInfoStr; parameters[2] = result; parameters[3] = now; parameters[4] = service; lock (ewsTasks) { RvLogger.DebugWrite("add the task in=============" + schedulingInfo.subject); ewsTasks.AddLast(parameters); } } } else { result = this.deleteMeeting(schedulingInfo, true); result.Detail = result.Detail == null ? "" : result.Detail; } if (false == result.Success && ("CONF_NOT_FOUND".Equals(result.Detail) || "CANCELLED".Equals(result.Detail))) result.Success = true; if (false == result.Success) { sendBackAMail(source, schedulingInfo, string.IsNullOrEmpty(result.ErrorCode) ? result.Detail : result.ErrorCode); } else if (successfullyRescheduled) sendBackAMail(source, schedulingInfo, "RESOURCE_SHORTAGE"); else if (IS_SEND_SUCCESS_MAIL) { sendBackAMail(source, schedulingInfo, "SUCCESS_NOTIFICATION"); } return result; }
void RvScopiaMeeting_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs args){ this.emailMessage = args.MailItem.Message; if (this.emailMessage == null || this.emailMessage.TnefPart == null) { return; } long now = DateTime.UtcNow.Ticks; SchedulingInfo schedulingInfo = new SchedulingInfo(); schedulingInfo.subject = args.MailItem.Message.Subject; schedulingInfo.delegatorEmailAddr = args.MailItem.Message.From.NativeAddress; RvLogger.DebugWrite("Enter transport agent, from: " + schedulingInfo.delegatorEmailAddr + ", subject: " + schedulingInfo.subject); try { this.agentAsyncContext = this.GetAgentAsyncContext(); schedulingInfo.requestType = this.getRequestType(this.emailMessage.MapiMessageClass); //Reject all meeting type except request and cancel. if (RequestType.Other == schedulingInfo.requestType) { RvLogger.DebugWrite("Reject other request type: " + this.emailMessage.MapiMessageClass); return; } RvMailParser parser = new RvMailParser(this); try { parser.parseTnefSimple(args.MailItem, schedulingInfo); } catch (Exception exceptionParseMail) { RvLogger.DebugWrite("Fail to parse mail."); RvLogger.DebugWrite(exceptionParseMail.Message); RvLogger.DebugWrite(exceptionParseMail.StackTrace); return; } //Reject forwarded appointment if (!string.IsNullOrEmpty(schedulingInfo.subjectPrefix) && "FW:".Equals(schedulingInfo.subjectPrefix)) { RvLogger.DebugWrite("Reject forward request type"); return; } if (schedulingInfo.recurrencePattern != null){ schedulingInfo.recurrenceHashInfo = RvScopiaMeeting.getHashString4Str(schedulingInfo.recurrencePattern.getStringForHash()); schedulingInfo.recurrencePattern.startDate = schedulingInfo.startDate; schedulingInfo.recurrencePattern.endDate = schedulingInfo.endDate; } if (null == schedulingInfo.emailMessage) { RvLogger.DebugWrite("null == schedulingInfo.emailMessage================================================"); return; } if (!isScopia(schedulingInfo)) { RvLogger.DebugWrite("This is not a SCOPIA meeting"); return; } parseRecipentsChanged(schedulingInfo); if (schedulingInfo.isRecipentsChanged) if (schedulingInfo.requestType == RequestType.CancelMeeting) { schedulingInfo.requestType = RequestType.CreateMeeting; schedulingInfo.isAddRecipents = false; schedulingInfo.subject = schedulingInfo.subject.Substring(schedulingInfo.subjectPrefix.Length + 1); Thread.Sleep(HOW_MANY_SECONDS_WAIT_FOR_FOLLOWING_REQUEST * 1000); }else schedulingInfo.isAddRecipents = true; if (RvScopiaMeeting.SERVER_ACCOUNT.Equals(schedulingInfo.senderEmailAddr)) { RvLogger.DebugWrite("Send a email back to notify the sender this mail is failed to send out."); return; } //when modify a recurrence, to make sure the modified ocurrence request is later than the recurrence request. if (schedulingInfo.meetingType == MeetingType.Ocurrence) Thread.Sleep(HOW_MANY_SECONDS_WAIT_FOR_FOLLOWING_REQUEST * 1000); icm.XmlApi.scheduleReportType result = changeMail(source, args, schedulingInfo, now); if (null != result && result.Success && isCreateMeetingRequest(schedulingInfo)) { Dictionary<string, byte[]> attachmentsdata = null; if (this.emailMessage.Attachments.Count > 0) { attachmentsdata = new Dictionary<string, byte[]>(this.emailMessage.Attachments.Count); for (int i = 0; i < this.emailMessage.Attachments.Count; i++) { Attachment attachment = this.emailMessage.Attachments[i]; Stream readStream = attachment.GetContentReadStream(); byte[] bytes = null; if (readStream.Length > 0) { bytes = new byte[readStream.Length]; readStream.Read(bytes, 0, bytes.Length); } else bytes = Encoding.ASCII.GetBytes(" "); attachmentsdata.Add(attachment.FileName, bytes); } } parser.changeBodyOfTnef(args.MailItem.Message.TnefPart, schedulingInfo); if (attachmentsdata != null) { foreach (KeyValuePair<string, byte[]> attachmentdata in attachmentsdata) { Attachment attachment = this.emailMessage.Attachments.Add(attachmentdata.Key); Stream attachmentStream = attachment.GetContentWriteStream(); attachmentStream.Write(attachmentdata.Value, 0, attachmentdata.Value.Length); attachmentStream.Flush(); attachmentStream.Close(); } } } } catch (Exception ex) { RvLogger.DebugWrite(ex.Message); RvLogger.DebugWrite(ex.StackTrace); string baseFailCode = ex.Message; sendBackAMail(source, schedulingInfo, baseFailCode); } finally { RvLogger.DebugWrite("Start to agentAsyncContext.Complete()================================================"); agentAsyncContext.Complete(); RvLogger.DebugWrite("Complete agentAsyncContext.Complete()================================================"); RvLogger.DebugWrite("Leave transport agent, from: " + schedulingInfo.delegatorEmailAddr + ", subject: " + schedulingInfo.subject); } }
void WSPRoutingAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs e) { try { WriteLine("Start WSPRoutingAgent_OnResolvedMessage"); WriteLine("\tFromAddress: " + e.MailItem.FromAddress.ToString()); WriteLine("\tSubject: " + e.MailItem.Message.Subject.ToString()); WriteLine("\tMapiMessageClass: " + e.MailItem.Message.MapiMessageClass.ToString()); MimeDocument mdMimeDoc = e.MailItem.Message.MimeDocument; HeaderList hlHeaderlist = mdMimeDoc.RootPart.Headers; Header mhProcHeader = hlHeaderlist.FindFirst("X-WSP"); if (mhProcHeader == null) { WriteLine("\tTouched: " + "No"); if (!e.MailItem.Message.IsSystemMessage) { bool touched = false; if (e.MailItem.FromAddress.DomainPart != null) { foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { WriteLine("\t\tFrom: " + e.MailItem.Message.From.SmtpAddress.ToString().ToLower()); WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); string[] tmpFrom = e.MailItem.Message.From.SmtpAddress.Split('@'); string[] tmpTo = recp.Address.ToString().Split('@'); if (IsMessageBetweenTenants(tmpFrom[1].ToLower(), tmpTo[1].ToLower())) { WriteLine("\t\tMessage routed to domain: " + tmpTo[1].ToLower() + routingDomain); RoutingDomain myRoutingDomain = new RoutingDomain(tmpTo[1].ToLower() + routingDomain); RoutingOverride myRoutingOverride = new RoutingOverride(myRoutingDomain, DeliveryQueueDomain.UseOverrideDomain); source.SetRoutingOverride(recp, myRoutingOverride); touched = true; } } } else { if ((e.MailItem.Message.MapiMessageClass.ToString() == "IPM.Note.Rules.OofTemplate.Microsoft") & blockInternalInterTenantOOF) { WriteLine("\t\tOOF From: " + e.MailItem.Message.From.SmtpAddress); if (e.MailItem.Message.From.SmtpAddress.Contains("@")) { string[] tmpFrom = e.MailItem.Message.From.SmtpAddress.Split('@'); foreach (EnvelopeRecipient recp in e.MailItem.Recipients) { WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); string[] tmpTo = recp.Address.ToString().Split('@'); if (IsMessageBetweenTenants(tmpFrom[1].ToLower(), tmpTo[1].ToLower())) { WriteLine("\t\tRemove: " + tmpTo[1].ToLower()); e.MailItem.Recipients.Remove(recp); } } } } } if (touched) { MimeNode lhLasterHeader = hlHeaderlist.LastChild; TextHeader nhNewHeader = new TextHeader("X-WSP", "Logged00"); hlHeaderlist.InsertBefore(nhNewHeader, lhLasterHeader); } } else WriteLine("\tSystem Message"); } else WriteLine("\tTouched: " + "Yes"); } catch (Exception ex) { WriteLine("\t[Error] Error :" + ex.Message); LogErrorToEventLog("[Error] [OnResolvedMessage] Error :" + ex.Message); } WriteLine("End WSPRoutingAgent_OnResolvedMessage"); }
// Tally the bandwidth cost for a message's sender and/or recipients. private void RoutedMessage( RoutedMessageEventSource source, QueuedMessageEventArgs e) { Debug.WriteLine(logPrefix + "Message routed"); long inboundMessageSize = 0; long outboundMessageSize = 0; Header sizeHeader = e.MailItem.Message.MimeDocument.RootPart.Headers.FindFirst(sizeHeaderName); if (null != sizeHeader) { // For inbound messages, the size that matters is the size that // was measured when the message was submitted. if (!long.TryParse(sizeHeader.Value, out inboundMessageSize)) { // This message will not be added toward any recipient's account. Debug.WriteLine(logPrefix + "Unable to parse message size header"); } } // For outbound messages, the size that matters is the size // of the message during routing. outboundMessageSize = e.MailItem.Message.MimeDocument.WriteTo(Stream.Null); foreach (EnvelopeRecipient recipient in e.MailItem.Recipients) { string rcptDomain = recipient.Address.DomainPart; // If the recipient domain is not in the organization, the // message is going out of the organization and should be added // to the outbound log of the sender. AcceptedDomain acceptedDomain = this.server.AcceptedDomains.Find(rcptDomain); if ((null == acceptedDomain) || (!acceptedDomain.IsInCorporation)) { // Only tally messages for members of the logging group. if (!server.AddressBook.IsMemberOf(e.MailItem.FromAddress, loggingGroup)) { continue; } // Get the primary address of the sender. AddressBookEntry senderInfo = this.server.AddressBook.Find(e.MailItem.FromAddress); if (null == senderInfo) { Debug.WriteLine(logPrefix + "Sender " + e.MailItem.FromAddress + " is not in the directory"); continue; } // Add the outbound size to the usage record of the sender. lock (BandwidthLogger.records) { BandwidthUsageRecord record = this.GetUsageRecord(senderInfo.PrimaryAddress); record.Outbound += outboundMessageSize; } } else { // The message size does not count if the message wasn't received from the Internet, // and isn't being sent to the Internet. if (0 == inboundMessageSize) { continue; } // Only tally messages for members of the logging group. if (!server.AddressBook.IsMemberOf(recipient.Address, loggingGroup)) { continue; } // Get the recipient primary address. AddressBookEntry recipientInfo = this.server.AddressBook.Find(recipient.Address); if (null == recipientInfo) { Debug.WriteLine(logPrefix + "Recipient " + recipient.Address + " is not in the directory"); continue; } // Add the inbound size to the recipient's usage record. lock (BandwidthLogger.records) { BandwidthUsageRecord record = this.GetUsageRecord(recipientInfo.PrimaryAddress); record.Inbound += inboundMessageSize; } } } }
public void MySubmittedMessageHandler(SubmittedMessageEventSource source, QueuedMessageEventArgs e) { e.MailItem.Message.Subject = "This message passed through my agent: " + e.MailItem.Message.Subject; }
private void WhenMessageCategorized(CategorizedMessageEventSource source, QueuedMessageEventArgs e) { Logger.LogDebug("Got new message, checking if I can sign it..."); try { this.agentAsyncContext = this.GetAgentAsyncContext(); #if !EX_2007_SP3 //not supported in Exchange 2007 this.agentAsyncContext.Resume(); #endif this.SignMailItem(e.MailItem); } catch (Exception ex) { Logger.LogError("Signing a mail item according to DKIM failed with an exception. Check the logged exception for details.\n" + ex.ToString()); } finally { this.agentAsyncContext.Complete(); } }