private SharepointAccessManager.Key GetKey(SecurityIdentifier userSid, Guid mailboxGuid) { SharepointAccessManager.Key result; using (HMACSHA256Cng hmacsha256Cng = new HMACSHA256Cng(this.hmacKey)) { byte[] array = new byte[userSid.BinaryLength + 16]; userSid.GetBinaryForm(array, 0); Buffer.BlockCopy(mailboxGuid.ToByteArray(), 0, array, userSid.BinaryLength, 16); byte[] src = hmacsha256Cng.ComputeHash(array); byte[] array2 = new byte[16]; Buffer.BlockCopy(src, 0, array2, 0, 16); result = new SharepointAccessManager.Key(array2); } return(result); }
private void SetValue(int sessionHashCode, SharepointAccessManager.Key key, SecurityIdentifier userSid, Guid mailboxGuid, AccessState value) { DateTime dateTime; lock (this.lockObj) { this.cache.Remove(key); dateTime = ((value == AccessState.Allowed) ? (DateTime.UtcNow + this.cacheExpiryForAllowedIdentity) : (DateTime.UtcNow + this.cacheExpiryForDeniedIdentity)); this.cache.AddAbsolute(key, value, dateTime, null); } ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug((long)sessionHashCode, "SharepointAccessManager.SetValue: Add to cache {0} for user {1}, site mailbox {2}. Expiry is {3}", new object[] { value, userSid, mailboxGuid, dateTime }); }
private bool TryGetValue(SharepointAccessManager.Key key, out AccessState value) { bool result; lock (this.lockObj) { if (!this.cache.TryGetValue(key, out value)) { this.cache.AddAbsolute(key, AccessState.Pending, DateTime.UtcNow + this.requestTimeout + TimeSpan.FromSeconds(5.0), null); result = false; } else { result = true; } } return(result); }
private bool UpdateAccessTokenIfNeeded(Uri sharepointUrl, ExchangePrincipal siteMailbox, ICredentials accessingUserCredential, ClientSecurityContext accessingUserSecurityContext, int sessionHashCode, out Exception exception, bool isTest = false) { exception = null; if (siteMailbox == null) { throw new ArgumentNullException("siteMailbox"); } if (accessingUserSecurityContext == null) { throw new ArgumentNullException("accessingUserSecurityContext"); } if (sharepointUrl == null) { ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug <string>((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Skip site mailbox {0} because its Sharepoint URL is null", siteMailbox.MailboxInfo.PrimarySmtpAddress.ToString()); return(false); } ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug <ClientSecurityContext, string, string>((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Entered with user {0}, site mailbox {1}, URL {2}", accessingUserSecurityContext, siteMailbox.MailboxInfo.PrimarySmtpAddress.ToString(), sharepointUrl.AbsoluteUri); LoggingContext loggingContext = new LoggingContext(siteMailbox.MailboxInfo.MailboxGuid, sharepointUrl.AbsoluteUri, accessingUserSecurityContext.ToString(), null); AccessState accessState = AccessState.Denied; bool flag = false; SharepointAccessManager.Key key = this.GetKey(accessingUserSecurityContext.UserSid, siteMailbox.MailboxInfo.MailboxGuid); if (!SharepointAccessManager.Instance.TryGetValue(key, out accessState)) { flag = true; ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Cache miss, query Sharepoint"); SharepointAccessManager.PermissionCheckerClient permissionCheckerClient = new SharepointAccessManager.PermissionCheckerClient(sessionHashCode, siteMailbox.MailboxInfo.MailboxGuid, sharepointUrl.AbsoluteUri, accessingUserSecurityContext.UserSid, key, accessingUserCredential, this.requestTimeout, this.requestThroughLocalProxy, isTest); LazyAsyncResult lazyAsyncResult = (LazyAsyncResult)permissionCheckerClient.BeginExecute(new AsyncCallback(SharepointAccessManager.OnCheckComplete), permissionCheckerClient); int num = (int)this.synchronousWaitTimeout.TotalSeconds * 2; int num2 = 0; while (!lazyAsyncResult.IsCompleted || lazyAsyncResult.Result == null) { Thread.Sleep(500); num2++; if (num2 > num) { break; } } object result = lazyAsyncResult.Result; if (!(result is AccessState)) { exception = ((lazyAsyncResult.Result is Exception) ? (lazyAsyncResult.Result as Exception) : new TimeoutException("Timed out")); WebException ex = exception as WebException; if (ex != null) { SharePointException exception2 = new SharePointException(sharepointUrl.AbsoluteUri, ex, false); ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceError <WebExceptionStatus, string, Exception>((long)permissionCheckerClient.SessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Query failed with WebException. Status: {0}, Message: {1}, InnerException: {2}", ex.Status, ex.Message, ex.InnerException); ProtocolLog.LogError(ProtocolLog.Component.SharepointAccessManager, loggingContext, "Query failed with SharePointException", exception2); } else { ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceError <Type, string, Exception>((long)permissionCheckerClient.SessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Query failed with {0}, Message: {1}, InnerException: {2}", exception.GetType(), exception.Message, exception.InnerException); ProtocolLog.LogError(ProtocolLog.Component.SharepointAccessManager, loggingContext, string.Format("Query failed with {0}", exception.GetType()), exception); } return(false); } accessState = (AccessState)result; } else if (accessState == AccessState.Pending) { ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Skip because there is an pending request"); return(true); } if (accessState == AccessState.Allowed) { if (!accessingUserSecurityContext.AddGroupSids(new SidBinaryAndAttributes[] { new SidBinaryAndAttributes(WellKnownSids.SiteMailboxGrantedAccessMembers, 4U) })) { ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceError((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Failed to add SiteMailboxGrantedAccessMembers group sid to access token"); return(false); } ExTraceGlobals.SiteMailboxPermissionCheckTracer.TraceDebug <ClientSecurityContext, string, string>((long)sessionHashCode, "SharepointAccessManager.UpdateAccessTokenIfNeeded: Access is allowed for user {0}, site mailbox {1}, URL {2}", accessingUserSecurityContext, siteMailbox.MailboxInfo.PrimarySmtpAddress.ToString(), sharepointUrl.AbsoluteUri); if (flag) { ProtocolLog.LogInformation(ProtocolLog.Component.SharepointAccessManager, loggingContext, string.Format("Allow access for site mailbox {0}, URL {1}", siteMailbox.MailboxInfo.PrimarySmtpAddress.ToString(), sharepointUrl)); } } else if (flag) { ProtocolLog.LogInformation(ProtocolLog.Component.SharepointAccessManager, loggingContext, string.Format("Deny access for site mailbox {0}, URL {1}", siteMailbox.MailboxInfo.PrimarySmtpAddress.ToString(), sharepointUrl)); } return(true); }
public PermissionCheckerClient(int sessionHashCode, Guid mailboxGuid, string siteUrl, SecurityIdentifier userSid, SharepointAccessManager.Key key, ICredentials credential, TimeSpan requestTimeout, int requestThroughLocalProxy, bool isTest) { this.SessionHashCode = sessionHashCode; this.MailboxGuid = mailboxGuid; this.siteUrl = siteUrl; this.UserSid = userSid; this.Key = key; this.credential = credential; this.requestTimeout = requestTimeout; this.requestThroughLocalProxy = requestThroughLocalProxy; this.isTest = isTest; }