private EncryptedSharedFolderData Encrypt(RequestedToken requestedToken, SharedFolderData sharedFolderData) { XmlElement xmlElement; try { xmlElement = sharedFolderData.SerializeToXmlElement(); } catch (InvalidOperationException innerException) { throw new UnableToGenerateEncryptedSharedFolderDataException(innerException); } XmlElement encryptedData; try { encryptedData = SymmetricEncryptedXml.Encrypt(xmlElement, requestedToken.ProofToken); } catch (CryptographicException innerException2) { throw new UnableToGenerateEncryptedSharedFolderDataException(innerException2); } return(new EncryptedSharedFolderData { Token = new EncryptedDataContainer { EncryptedData = requestedToken.SecurityToken }, Data = new EncryptedDataContainer { EncryptedData = encryptedData } }); }
private SharedFolderData GetMatchingSharedFolderData(SharingContext context, ADRecipient mailboxOwner) { SharedFolderDataEncryption sharedFolderDataEncryption = new SharedFolderDataEncryption(ExternalAuthentication.GetCurrent()); bool flag = false; ExTraceGlobals.SharingTracer.TraceDebug <ADRecipient>((long)this.GetHashCode(), "{0}: Decrypting the encrypted shared folder data.", mailboxOwner); foreach (EncryptedSharedFolderData encryptedSharedFolderData in context.EncryptedSharedFolderDataCollection) { SharedFolderData sharedFolderData = sharedFolderDataEncryption.TryDecrypt(encryptedSharedFolderData); if (sharedFolderData != null) { if (SharingProviderHandlerExternal.TryFindMatchingRecipient(sharedFolderData, mailboxOwner) != null) { ExTraceGlobals.SharingTracer.TraceDebug <ADRecipient>((long)this.GetHashCode(), "{0}: Get the decrypted shared folder data.", mailboxOwner); return(sharedFolderData); } flag = true; } } ExTraceGlobals.SharingTracer.TraceError <ADRecipient>((long)this.GetHashCode(), "{0}: Failed to decrypt shared folder data.", mailboxOwner); if (flag) { throw new InvalidExternalSharingSubscriberException(); } throw new InvalidSharingDataException("SharedFolderData", string.Empty); }
protected override SubscribeResults InternalPerformSubscribe(MailboxSession mailboxSession, SharingContext context) { ADRecipient mailboxOwner = DirectoryHelper.ReadADRecipient(mailboxSession.MailboxOwner.MailboxInfo.MailboxGuid, mailboxSession.MailboxOwner.MailboxInfo.IsArchive, mailboxSession.GetADRecipientSession(true, ConsistencyMode.IgnoreInvalid)); SharedFolderData matchingSharedFolderData = this.GetMatchingSharedFolderData(context, mailboxOwner); if (context.InitiatorSmtpAddress == null) { throw new InvalidSharingDataException("InitiatorSmtpAddress", string.Empty); } IdAndName idAndName = null; StoreObjectId storeObjectId = null; using (SharingSubscriptionManager sharingSubscriptionManager = new SharingSubscriptionManager(mailboxSession)) { SharingSubscriptionData sharingSubscriptionData = this.CreateSubscriptionData(mailboxOwner, context, matchingSharedFolderData); SharingFolderManager sharingFolderManager = new SharingFolderManager(mailboxSession); SharingSubscriptionData existing = sharingSubscriptionManager.GetExisting(sharingSubscriptionData.Key); if (existing != null) { existing.CopyFrom(sharingSubscriptionData); } SharingSubscriptionData sharingSubscriptionData2 = existing ?? sharingSubscriptionData; idAndName = sharingFolderManager.EnsureFolder(sharingSubscriptionData2); if (sharingSubscriptionData2.LocalFolderId == null || !sharingSubscriptionData2.LocalFolderId.Equals(idAndName.Id)) { storeObjectId = (sharingSubscriptionData2.LocalFolderId = idAndName.Id); } SharingSubscriptionData sharingSubscriptionData3 = sharingSubscriptionManager.CreateOrUpdate(sharingSubscriptionData2, false); if (!sharingSubscriptionData2.LocalFolderId.Equals(sharingSubscriptionData3.LocalFolderId)) { idAndName = sharingFolderManager.GetFolder(sharingSubscriptionData3); } } return(new SubscribeResultsExternal(context.DataType, context.InitiatorSmtpAddress, context.InitiatorName, context.FolderName, matchingSharedFolderData.FolderId, idAndName.Id, storeObjectId != null, idAndName.Name)); }
private SharedFolderDataRecipient GetMatchingRecipient(SharedFolderData sharedFolderData, ADRecipient mailboxOwner) { SharedFolderDataRecipient sharedFolderDataRecipient = SharingProviderHandlerExternal.TryFindMatchingRecipient(sharedFolderData, mailboxOwner); if (sharedFolderDataRecipient != null) { return(sharedFolderDataRecipient); } ExTraceGlobals.SharingTracer.TraceError <ADRecipient>((long)this.GetHashCode(), "{0}: The sharing message is not intended to this subscriber.", mailboxOwner); throw new InvalidExternalSharingSubscriberException(); }
public SharedFolderData Decrypt(EncryptedSharedFolderData[] encryptedSharedFolderDataCollection) { foreach (EncryptedSharedFolderData encryptedSharedFolderData in encryptedSharedFolderDataCollection) { SharedFolderData sharedFolderData = this.TryDecrypt(encryptedSharedFolderData); if (sharedFolderData != null) { return(sharedFolderData); } } throw new InvalidEncryptedSharedFolderDataException(); }
private static SharedFolderDataRecipient TryFindMatchingRecipient(SharedFolderData sharedFolderData, ADRecipient mailboxOwner) { foreach (SharedFolderDataRecipient sharedFolderDataRecipient in sharedFolderData.Recipients) { if (mailboxOwner.IsAnyAddressMatched(new string[] { sharedFolderDataRecipient.SmtpAddress })) { return(sharedFolderDataRecipient); } } return(null); }
public EncryptionResults Encrypt(IExchangePrincipal mailboxOwner, IRecipientSession recipientSession, ExternalUserCollection externalUserCollection, ValidRecipient[] recipients, string sender, string containerClass, string folderId, IFrontEndLocator frontEndLocator) { SharingDataType sharingDataType = SharingDataType.FromContainerClass(containerClass); if (sharingDataType == null || !sharingDataType.IsExternallySharable) { throw new ArgumentOutOfRangeException("containerClass"); } ADUser aduser = DirectoryHelper.ReadADRecipient(mailboxOwner.MailboxInfo.MailboxGuid, mailboxOwner.MailboxInfo.IsArchive, recipientSession) as ADUser; if (aduser == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, string>((long)this.GetHashCode(), "{0}: The Active Directory user was not found. Sender={1}.", this, sender); throw new ObjectNotFoundException(ServerStrings.ADUserNotFound); } ProxyAddress item = new SmtpProxyAddress(sender, false); if (!aduser.EmailAddresses.Contains(item)) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, string>((long)this.GetHashCode(), "{0}: The SMTP address was not found in the user AD object for this mailbox. Sender={1}.", this, sender); throw new ObjectNotFoundException(ServerStrings.ADUserNotFound); } SharingPolicy sharingPolicy = DirectoryHelper.ReadSharingPolicy(mailboxOwner.MailboxInfo.MailboxGuid, mailboxOwner.MailboxInfo.IsArchive, recipientSession); SharedFolderDataEncryption.Tracer.TraceDebug <SharedFolderDataEncryption, object>((long)this.GetHashCode(), "{0}: Sharing policy to be applied to this user: {1}", this, (sharingPolicy == null) ? "<null>" : sharingPolicy.Id); SharingPolicyAction sharingPolicyActions = SharedFolderDataEncryption.GetSharingPolicyActions(sharingDataType.StoreObjectType); SharedFolderDataRecipient[] externalIdentities = SharedFolderDataEncryption.GetExternalIdentities(externalUserCollection, recipients); List <InvalidRecipient> list = new List <InvalidRecipient>(); Dictionary <TokenTarget, List <SharedFolderDataRecipient> > dictionary = new Dictionary <TokenTarget, List <SharedFolderDataRecipient> >(externalIdentities.Length, SharedFolderDataEncryption.TokenTargetComparer); for (int i = 0; i < recipients.Length; i++) { SharedFolderDataRecipient item2 = externalIdentities[i]; ValidRecipient validRecipient = recipients[i]; SmtpAddress smtpAddress = new SmtpAddress(validRecipient.SmtpAddress); string domain = smtpAddress.Domain; if (sharingPolicy == null || !sharingPolicy.IsAllowedForAnySharing(domain, sharingPolicyActions)) { SharedFolderDataEncryption.Tracer.TraceDebug <string>((long)this.GetHashCode(), "Sharing policy does not allow user to share with domain {0}", domain); list.Add(new InvalidRecipient(validRecipient.SmtpAddress, InvalidRecipientResponseCodeType.SystemPolicyBlocksSharingWithThisRecipient)); } else { SmtpAddress smtpAddress2 = new SmtpAddress(validRecipient.SmtpAddressForEncryption); TokenTarget tokenTarget = TargetUriResolver.Resolve(smtpAddress2.Domain, aduser.OrganizationId); if (tokenTarget == null) { list.Add(new InvalidRecipient(validRecipient.SmtpAddress, InvalidRecipientResponseCodeType.RecipientOrganizationNotFederated)); } else { List <SharedFolderDataRecipient> list2; if (!dictionary.TryGetValue(tokenTarget, out list2)) { list2 = new List <SharedFolderDataRecipient>(1); dictionary.Add(tokenTarget, list2); } list2.Add(item2); } } } List <EncryptedSharedFolderData> list3 = new List <EncryptedSharedFolderData>(dictionary.Count); SharedFolderData sharedFolderData = new SharedFolderData(); sharedFolderData.DataType = sharingDataType.ExternalName; sharedFolderData.FolderId = folderId; sharedFolderData.SharingUrl = this.GetSharingUrl(aduser, frontEndLocator); sharedFolderData.FederationUri = this.externalAuthentication.TokenValidator.TargetUri.ToString(); sharedFolderData.SenderSmtpAddress = sender; DelegationTokenRequest delegationTokenRequest = new DelegationTokenRequest { FederatedIdentity = aduser.GetFederatedIdentity(), EmailAddress = aduser.GetFederatedSmtpAddress(new SmtpAddress(sender)).ToString(), Offer = Offer.SharingInviteMessage }; SecurityTokenService securityTokenService = this.externalAuthentication.GetSecurityTokenService(aduser.OrganizationId); foreach (KeyValuePair <TokenTarget, List <SharedFolderDataRecipient> > keyValuePair in dictionary) { delegationTokenRequest.Target = keyValuePair.Key; sharedFolderData.Recipients = keyValuePair.Value.ToArray(); try { RequestedToken requestedToken = securityTokenService.IssueToken(delegationTokenRequest); list3.Add(this.Encrypt(requestedToken, sharedFolderData)); } catch (WSTrustException ex) { foreach (SharedFolderDataRecipient sharedFolderDataRecipient in sharedFolderData.Recipients) { list.Add(new InvalidRecipient(sharedFolderDataRecipient.SmtpAddress, SharedFolderDataEncryption.GetResponseCodeFromException(ex), ex.ToString())); } } } return(new EncryptionResults(list3.ToArray(), list.ToArray())); }
public SharedFolderData TryDecrypt(EncryptedSharedFolderData encryptedSharedFolderData) { if (encryptedSharedFolderData.Token == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption>((long)this.GetHashCode(), "{0}: EncryptedSharedFolderData is missing Token element.", this); return(null); } if (encryptedSharedFolderData.Token.EncryptedData == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption>((long)this.GetHashCode(), "{0}: EncryptedSharedFolderData.Token is missing <EncryptedData> element.", this); return(null); } if (encryptedSharedFolderData.Data == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption>((long)this.GetHashCode(), "{0}: EncryptedSharedFolderData is missing <Data> element.", this); return(null); } if (encryptedSharedFolderData.Data.EncryptedData == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption>((long)this.GetHashCode(), "{0}: EncryptedSharedFolderData.Data is missing <EncryptedData> element.", this); return(null); } TokenValidationResults tokenValidationResults = this.externalAuthentication.TokenValidator.ValidateToken(encryptedSharedFolderData.Token.EncryptedData, Offer.SharingInviteMessage); if (tokenValidationResults.Result != TokenValidationResult.Valid) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, TokenValidationResults>((long)this.GetHashCode(), "{0}: Token is not valid. TokenValidationResults={1}", this, tokenValidationResults); return(null); } SymmetricSecurityKey proofToken = tokenValidationResults.ProofToken; if (proofToken == null) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption>((long)this.GetHashCode(), "{0}: Unable to retrieve the security key from the token.", this); return(null); } XmlElement xmlElement; try { xmlElement = SymmetricEncryptedXml.Decrypt(encryptedSharedFolderData.Data.EncryptedData, proofToken); } catch (CryptographicException arg) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, CryptographicException>((long)this.GetHashCode(), "{0}: Unable to decrypt the data element. Exception={1}", this, arg); return(null); } SharedFolderData result; try { result = SharedFolderData.DeserializeFromXmlELement(xmlElement); } catch (InvalidOperationException arg2) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, InvalidOperationException>((long)this.GetHashCode(), "{0}: Unable to deserialize the data element. InvalidOperationException={1}", this, arg2); result = null; } catch (XmlException arg3) { SharedFolderDataEncryption.Tracer.TraceError <SharedFolderDataEncryption, XmlException>((long)this.GetHashCode(), "{0}: Unable to deserialize the data element. XmlException={1}", this, arg3); result = null; } return(result); }
private SharingSubscriptionData CreateSubscriptionData(ADRecipient mailboxOwner, SharingContext context, SharedFolderData sharedFolderData) { SharedFolderDataRecipient matchingRecipient = this.GetMatchingRecipient(sharedFolderData, mailboxOwner); if (sharedFolderData.FederationUri == null) { throw new InvalidSharingDataException("FederationUri", string.Empty); } if (!Uri.IsWellFormedUriString(sharedFolderData.FederationUri, UriKind.Absolute)) { throw new InvalidSharingDataException("FederationUri", sharedFolderData.FederationUri); } if (sharedFolderData.SharingUrl == null) { throw new InvalidSharingDataException("SharingUrl", string.Empty); } if (!Uri.IsWellFormedUriString(sharedFolderData.SharingUrl, UriKind.Absolute)) { throw new InvalidSharingDataException("SharingUrl", sharedFolderData.SharingUrl); } return(new SharingSubscriptionData(sharedFolderData.DataType, context.InitiatorSmtpAddress, context.InitiatorName, sharedFolderData.FolderId, context.FolderName, context.IsPrimary, new Uri(sharedFolderData.FederationUri), new Uri(sharedFolderData.SharingUrl), null, matchingRecipient.SharingKey, matchingRecipient.SmtpAddress)); }