|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Channels
{
using System.Runtime.CompilerServices;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.ServiceModel;
using System.ServiceModel.Security;
using System.Transactions;
using System.ServiceModel.Security.Tokens;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using SR = System.ServiceModel.SR;
class MsmqOutputMessage<TChannel> : NativeMsmqMessage
{
BufferProperty body;
IntProperty bodyType;
ByteProperty delivery;
IntProperty timeToReachQueue;
IntProperty timeToBeReceived;
ByteProperty journal;
StringProperty deadLetterQueue;
IntProperty senderIdType;
IntProperty authLevel;
BufferProperty senderCert;
IntProperty privLevel;
ByteProperty trace;
BufferProperty messageId;
IntProperty encryptionAlgorithm;
IntProperty hashAlgorithm;
public MsmqOutputMessage(MsmqChannelFactoryBase<TChannel> factory, int bodySize, EndpointAddress remoteAddress)
: this(factory, bodySize, remoteAddress, 0)
{
}
protected MsmqOutputMessage(MsmqChannelFactoryBase<TChannel> factory, int bodySize, EndpointAddress remoteAddress, int additionalPropertyCount)
: base(15 + additionalPropertyCount)
{
this.body = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_BODY, bodySize);
this.messageId = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_MSGID, UnsafeNativeMethods.PROPID_M_MSGID_SIZE);
EnsureBodyTypeProperty(UnsafeNativeMethods.VT_VECTOR | UnsafeNativeMethods.VT_UI1);
EnsureJournalProperty((byte)UnsafeNativeMethods.MQMSG_JOURNAL, factory.UseSourceJournal);
this.delivery = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_DELIVERY);
if (factory.Durable)
{
this.delivery.Value = (byte)UnsafeNativeMethods.MQMSG_DELIVERY_RECOVERABLE;
}
else
{
this.delivery.Value = (byte)UnsafeNativeMethods.MQMSG_DELIVERY_EXPRESS;
}
if (factory.TimeToLive != TimeSpan.MaxValue)
{
int totalSeconds = MsmqDuration.FromTimeSpan(factory.TimeToLive);
EnsureTimeToReachQueueProperty(totalSeconds);
this.timeToBeReceived = new IntProperty(this,
UnsafeNativeMethods.PROPID_M_TIME_TO_BE_RECEIVED, totalSeconds);
}
switch (factory.DeadLetterQueue)
{
case DeadLetterQueue.None:
EnsureJournalProperty((byte)UnsafeNativeMethods.MQMSG_DEADLETTER, false);
break;
case DeadLetterQueue.System:
EnsureJournalProperty((byte)UnsafeNativeMethods.MQMSG_DEADLETTER, true);
break;
case DeadLetterQueue.Custom:
EnsureJournalProperty((byte)UnsafeNativeMethods.MQMSG_DEADLETTER, true);
EnsureDeadLetterQueueProperty(factory.DeadLetterQueuePathName);
break;
}
if (MsmqAuthenticationMode.WindowsDomain == factory.MsmqTransportSecurity.MsmqAuthenticationMode)
{
EnsureSenderIdTypeProperty(UnsafeNativeMethods.MQMSG_SENDERID_TYPE_SID);
this.authLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_AUTH_LEVEL,
UnsafeNativeMethods.MQMSG_AUTH_LEVEL_ALWAYS);
this.hashAlgorithm = new IntProperty(
this,
UnsafeNativeMethods.PROPID_M_HASH_ALG,
MsmqSecureHashAlgorithmHelper.ToInt32(factory.MsmqTransportSecurity.MsmqSecureHashAlgorithm));
if (ProtectionLevel.EncryptAndSign == factory.MsmqTransportSecurity.MsmqProtectionLevel)
{
this.privLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_PRIV_LEVEL,
UnsafeNativeMethods.MQMSG_PRIV_LEVEL_BODY_ENHANCED);
this.encryptionAlgorithm = new IntProperty(
this,
UnsafeNativeMethods.PROPID_M_ENCRYPTION_ALG,
MsmqEncryptionAlgorithmHelper.ToInt32(factory.MsmqTransportSecurity.MsmqEncryptionAlgorithm));
}
}
else if (MsmqAuthenticationMode.Certificate == factory.MsmqTransportSecurity.MsmqAuthenticationMode)
{
this.authLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_AUTH_LEVEL,
UnsafeNativeMethods.MQMSG_AUTH_LEVEL_ALWAYS);
this.hashAlgorithm = new IntProperty(
this,
UnsafeNativeMethods.PROPID_M_HASH_ALG,
MsmqSecureHashAlgorithmHelper.ToInt32(factory.MsmqTransportSecurity.MsmqSecureHashAlgorithm));
if (ProtectionLevel.EncryptAndSign == factory.MsmqTransportSecurity.MsmqProtectionLevel)
{
this.privLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_PRIV_LEVEL,
UnsafeNativeMethods.MQMSG_PRIV_LEVEL_BODY_ENHANCED);
this.encryptionAlgorithm = new IntProperty(
this,
UnsafeNativeMethods.PROPID_M_ENCRYPTION_ALG,
MsmqEncryptionAlgorithmHelper.ToInt32(factory.MsmqTransportSecurity.MsmqEncryptionAlgorithm));
}
EnsureSenderIdTypeProperty(UnsafeNativeMethods.MQMSG_SENDERID_TYPE_NONE);
this.senderCert = new BufferProperty(this, UnsafeNativeMethods.PROPID_M_SENDER_CERT);
}
else
{
this.authLevel = new IntProperty(this, UnsafeNativeMethods.PROPID_M_AUTH_LEVEL,
UnsafeNativeMethods.MQMSG_AUTH_LEVEL_NONE);
EnsureSenderIdTypeProperty(UnsafeNativeMethods.MQMSG_SENDERID_TYPE_NONE);
}
this.trace = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_TRACE, (byte)(factory.UseMsmqTracing ?
UnsafeNativeMethods.MQMSG_SEND_ROUTE_TO_REPORT_QUEUE : UnsafeNativeMethods.MQMSG_TRACE_NONE));
}
public BufferProperty Body
{
get { return this.body; }
}
public BufferProperty MessageId
{
get { return this.messageId; }
}
internal void ApplyCertificateIfNeeded(SecurityTokenProviderContainer certificateTokenProvider, MsmqAuthenticationMode authenticationMode, TimeSpan timeout)
{
if (MsmqAuthenticationMode.Certificate == authenticationMode)
{
if (certificateTokenProvider == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("certificateTokenProvider");
}
X509Certificate2 clientCertificate = certificateTokenProvider.GetCertificate(timeout);
if (clientCertificate == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.MsmqCertificateNotFound)));
this.senderCert.SetBufferReference(clientCertificate.GetRawCertData());
}
}
protected void EnsureBodyTypeProperty(int value)
{
if (this.bodyType == null)
{
this.bodyType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_BODY_TYPE);
}
this.bodyType.Value = value;
}
protected void EnsureDeadLetterQueueProperty(string value)
{
if (value.Length > 0)
{
if (this.deadLetterQueue == null)
{
this.deadLetterQueue = new StringProperty(this, UnsafeNativeMethods.PROPID_M_DEADLETTER_QUEUE, value);
}
else
{
this.deadLetterQueue.SetValue(value);
}
}
}
protected void EnsureSenderIdTypeProperty(int value)
{
if (this.senderIdType == null)
{
this.senderIdType = new IntProperty(this, UnsafeNativeMethods.PROPID_M_SENDERID_TYPE);
}
this.senderIdType.Value = value;
}
protected void EnsureTimeToReachQueueProperty(int value)
{
if (this.timeToReachQueue == null)
{
this.timeToReachQueue = new IntProperty(this,
UnsafeNativeMethods.PROPID_M_TIME_TO_REACH_QUEUE);
}
this.timeToReachQueue.Value = value;
}
protected void EnsureJournalProperty(byte flag, bool isFlagSet)
{
if (this.journal == null)
{
this.journal = new ByteProperty(this, UnsafeNativeMethods.PROPID_M_JOURNAL);
}
if (isFlagSet)
{
this.journal.Value |= flag;
}
else
{
this.journal.Value &= (byte)(~flag);
}
}
}
}
|