private SafeProcThreadAttributeList AllocateAttributeList() { using (var localDisposalEscrow = new DisposalEscrow()) { SECURITY_CAPABILITIES securityCapabilities = new SECURITY_CAPABILITIES(); this.SetSecurityCapabilities( ref securityCapabilities, this.securityIdentifierHandle, new WELL_KNOWN_SID_TYPE[] { WELL_KNOWN_SID_TYPE.WinCapabilityInternetClientSid }); var attributeListHandle = localDisposalEscrow.Add(new SafeProcThreadAttributeList(1)); var securityCapabilitiesMemory = localDisposalEscrow.Add(new SafeHGlobalBuffer(Marshal.SizeOf(securityCapabilities))); Marshal.StructureToPtr(securityCapabilities, securityCapabilitiesMemory.DangerousGetHandle(), fDeleteOld: false); if (!Methods.UpdateProcThreadAttribute( attributeListHandle.DangerousGetHandle(), dwFlags: 0, attribute: PROC_THREAD_ATTRIBUTES.PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES, securityCapabilitiesMemory.DangerousGetHandle(), securityCapabilitiesMemory.Size, lpPreviousValue: IntPtr.Zero, lpReturnSize: IntPtr.Zero)) { throw new SandboxException( $"Failed to update proc thread attribute list (0x{Marshal.GetLastWin32Error():X08})", new Win32Exception());; } this.disposalEscrow.Subsume(localDisposalEscrow); return(attributeListHandle); } }
private AppContainer(ITracer tracer, string name, SafeSecurityIdentifier securityIdentifierHandle) { if (tracer == null) { throw new ArgumentNullException(nameof(tracer)); } if (name == null) { throw new ArgumentNullException(nameof(name)); } if (securityIdentifierHandle == null) { throw new ArgumentNullException(nameof(securityIdentifierHandle)); } this.Name = name; this.SecurityIdentifier = new SecurityIdentifier(securityIdentifierHandle.DangerousGetHandle()); if (Methods.GetAppContainerFolderPath(this.SecurityIdentifier.Value, out string folderPath) == HResult.OK) { this.FolderPath = folderPath; } this.disposalEscrow = new DisposalEscrow(); this.securityIdentifierHandle = securityIdentifierHandle; this.tracer = tracer; this.attributeListHandle = this.AllocateAttributeList(); }
public CobaltSession(string sessionId, string filePath, string login = "******", string name = "Anonymous", string email = "", bool isAnonymous = true) :base(sessionId, filePath, login, name, email, isAnonymous) { m_disposal = new DisposalEscrow(m_sessionId); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = true; content.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".Content"); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig(); coauth.IsNewFile = true; coauth.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".CoauthMetadata"); coauth.cellSchemaIsGenericFda = false; coauth.CellStorageConfig = new CellStorageConfig(); coauth.Schema = CobaltFilePartition.Schema.ShreddedCobalt; coauth.PartitionId = FilePartitionId.CoauthMetadata; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = true; wacupdate.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".WordWacUpdate"); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary<FilePartitionId, CobaltFilePartitionConfig> partitionConfs = new Dictionary<FilePartitionId, CobaltFilePartitionConfig>(); partitionConfs.Add(FilePartitionId.Content, content); partitionConfs.Add(FilePartitionId.WordWacUpdate, wacupdate); partitionConfs.Add(FilePartitionId.CoauthMetadata, coauth); m_cobaltFile = new CobaltFile(m_disposal, partitionConfs, new CobaltHostLockingStore(this), null); if (m_fileinfo.Exists) { String appdata_path = Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData); appdata_path = Path.Combine(appdata_path, @"WopiCobaltHost"); if (!Directory.Exists(appdata_path)) Directory.CreateDirectory(appdata_path); String cache_file = Path.Combine(appdata_path, m_fileinfo.Name); if (File.Exists(cache_file)) File.Delete(cache_file); File.Copy(m_fileinfo.FullName, cache_file, true); var file_atom = FileAtom.FromExisting(cache_file, m_disposal); //if want to avoid temp file, you can use memory Atom below //MemoryStream ms = new MemoryStream(); //using (FileStream fileStream = m_fileinfo.OpenRead()) //{ // fileStream.CopyTo(ms); //} //var src_atom = new AtomFromByteArray(ms.ToArray()); Cobalt.Metrics o1; m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, file_atom, out o1); m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } }
public WopiSession(string accessId, string filePath, string login = "******", string name = "Anonymous", string email = "", bool isAnonymous = true) { _accessId = accessId; _fileinfo = new FileInfo(filePath); _name = name; _login = login; _email = email; _isAnonymous = isAnonymous; _disposal = new DisposalEscrow(_accessId); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = true; content.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".Content"); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig(); coauth.IsNewFile = true; coauth.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".CoauthMetadata"); coauth.cellSchemaIsGenericFda = false; coauth.CellStorageConfig = new CellStorageConfig(); coauth.Schema = CobaltFilePartition.Schema.ShreddedCobalt; coauth.PartitionId = FilePartitionId.CoauthMetadata; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = true; wacupdate.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".WordWacUpdate"); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary <FilePartitionId, CobaltFilePartitionConfig> pd = new Dictionary <FilePartitionId, CobaltFilePartitionConfig>(); pd.Add(FilePartitionId.Content, content); pd.Add(FilePartitionId.WordWacUpdate, wacupdate); pd.Add(FilePartitionId.CoauthMetadata, coauth); _cobaltFile = new CobaltFile(_disposal, pd, new WopiHostLockingStore(this), null); if (_fileinfo.Exists) { var src = FileAtom.FromExisting(_fileinfo.FullName, _disposal); Cobalt.Metrics o1; _cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, src, out o1); _cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } }
private CobaltFile GetCobaltFile(IWopiFile file, ClaimsPrincipal principal) { var disposal = new DisposalEscrow(file.Owner); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, file.Identifier + @".Content"), cellSchemaIsGenericFda = true, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.Content }; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, file.Identifier + @".CoauthMetadata"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.CoauthMetadata }; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, file.Identifier + @".WordWacUpdate"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.WordWacUpdate }; Dictionary <FilePartitionId, CobaltFilePartitionConfig> partitionConfigs = new Dictionary <FilePartitionId, CobaltFilePartitionConfig> { { FilePartitionId.Content, content }, { FilePartitionId.WordWacUpdate, wacupdate }, { FilePartitionId.CoauthMetadata, coauth } }; var tempCobaltFile = new CobaltFile(disposal, partitionConfigs, new CobaltHostLockingStore(principal), null); if (file.Exists) { using (var stream = file.GetReadStream()) { var srcAtom = new AtomFromStream(stream); Metrics o1; tempCobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, srcAtom, out o1); tempCobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } } return(tempCobaltFile); }
public WopiSession(string accessId, string filePath, string login = "******", string name = "Anonymous", string email = "", bool isAnonymous = true) { _accessId = accessId; _fileinfo = new FileInfo(filePath); _name = name; _login = login; _email = email; _isAnonymous = isAnonymous; _disposal = new DisposalEscrow(_accessId); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = true; content.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".Content"); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig(); coauth.IsNewFile = true; coauth.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".CoauthMetadata"); coauth.cellSchemaIsGenericFda = false; coauth.CellStorageConfig = new CellStorageConfig(); coauth.Schema = CobaltFilePartition.Schema.ShreddedCobalt; coauth.PartitionId = FilePartitionId.CoauthMetadata; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = true; wacupdate.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), _disposal, _accessId + @".WordWacUpdate"); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary<FilePartitionId, CobaltFilePartitionConfig> pd = new Dictionary<FilePartitionId, CobaltFilePartitionConfig>(); pd.Add(FilePartitionId.Content, content); pd.Add(FilePartitionId.WordWacUpdate, wacupdate); pd.Add(FilePartitionId.CoauthMetadata, coauth); _cobaltFile = new CobaltFile(_disposal, pd, new WopiHostLockingStore(this), null); if (_fileinfo.Exists) { var src = FileAtom.FromExisting(_fileinfo.FullName, _disposal); Cobalt.Metrics o1; _cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, src, out o1); _cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } }
public void Save(Stream stream) { this.SaveDiagnosticStream(stream, "Original.bin"); lock (this.synchronizationObject) { using (DisposalEscrow disposalEscrow = new DisposalEscrow("CobaltStore.Save")) { CobaltFile cobaltFile = this.CreateCobaltFile(disposalEscrow, true); CobaltFilePartition cobaltFilePartition = cobaltFile.GetCobaltFilePartition(FilePartitionId.Content); Metrics metrics; cobaltFilePartition.SetStream(GenericFda.ContentStreamId, new BytesFromStream(stream), ref metrics); cobaltFilePartition.CommitChanges(); this.SaveDiagnosticDocument(cobaltFile, "AfterSave.bin"); } } }
private static SID_AND_ATTRIBUTES ConvertSecurityIdentifierToSidAndAttributes( SecurityIdentifier securityIdentifier, DisposalEscrow disposalEscrow) { var sidBytes = new byte[securityIdentifier.BinaryLength]; securityIdentifier.GetBinaryForm(sidBytes, 0 /* offset */); var nativeBytes = disposalEscrow.Add(new SafeHGlobalBuffer(sidBytes.Length)); Marshal.Copy(sidBytes, 0 /* startIndex */, nativeBytes.DangerousGetHandle(), sidBytes.Length); return(new SID_AND_ATTRIBUTES { Sid = nativeBytes.DangerousGetHandle(), }); }
private void SetSecurityCapabilities( ref SECURITY_CAPABILITIES securityCapabilities, SafeSecurityIdentifier appContainerSid, WELL_KNOWN_SID_TYPE[] appCapabilities) { using (var localDisposalEscrow = new DisposalEscrow()) { securityCapabilities.AppContainerSid = appContainerSid.DangerousGetHandle(); securityCapabilities.Capabilities = IntPtr.Zero; securityCapabilities.CapabilityCount = 0; securityCapabilities.Reserved = 0; if (appCapabilities != null && appCapabilities.Length > 0) { var attributesMemory = localDisposalEscrow.Add(new SafeHGlobalBuffer(Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)) * appCapabilities.Length)); for (int i = 0; i < appCapabilities.Length; i++) { Int32 sidSize = Constants.SECURITY_MAX_SID_SIZE; var safeMemory = localDisposalEscrow.Add(new SafeHGlobalBuffer(sidSize)); if (!Methods.CreateWellKnownSid(appCapabilities[i], IntPtr.Zero, safeMemory, ref sidSize)) { throw new SandboxException( "Unable to create well known sid.", new Win32Exception()); } var attribute = new SID_AND_ATTRIBUTES { Attributes = SID_ATTRIBUTES.SE_GROUP_ENABLED, Sid = safeMemory.DangerousGetHandle(), }; Marshal.StructureToPtr(attribute, IntPtr.Add(attributesMemory.DangerousGetHandle(), i * Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES))), fDeleteOld: false); } securityCapabilities.Capabilities = attributesMemory.DangerousGetHandle(); securityCapabilities.CapabilityCount = appCapabilities.Length; } this.disposalEscrow.Subsume(localDisposalEscrow); } }
public Stream GetDocumentStream() { Stream result; lock (this.synchronizationObject) { using (DisposalEscrow disposalEscrow = new DisposalEscrow("CobaltStore.GetDocumentStream")) { CobaltFile cobaltFile = this.CreateCobaltFile(disposalEscrow, false); CobaltFilePartition cobaltFilePartition = cobaltFile.GetCobaltFilePartition(FilePartitionId.Content); Bytes stream = cobaltFilePartition.GetStream(CobaltFilePartition.ContentStreamId); Stream stream2 = new StreamFromBytes(stream, 0UL); Stream stream3 = new StreamDisposalWrapper(stream2, disposalEscrow.Transfer("GetDocumentStream-StreamDisposalWrapper")); result = stream3; } } return(result); }
public CobaltFile Create(int accessTokenId) { var disposal = new DisposalEscrow(accessTokenId.ToString(CultureInfo.InvariantCulture)); var content = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".Content"), cellSchemaIsGenericFda = true, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.Content }; var coauth = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".CoauthMetadata"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.CoauthMetadata }; var wacupdate = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".WordWacUpdate"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.WordWacUpdate }; var partitionConfs = new Dictionary<FilePartitionId, CobaltFilePartitionConfig> { {FilePartitionId.Content, content}, {FilePartitionId.WordWacUpdate, wacupdate}, {FilePartitionId.CoauthMetadata, coauth} }; var cobaltFile = new CobaltFile(disposal, partitionConfs, new CobaltHostLockingStore(), null); var token = _tokenManager.GetToken(accessTokenId); Atom atom; if (_webDavManager.FileExist(token.FilePath)) { var fileBytes = _webDavManager.GetFileBytes(token.FilePath); atom = new AtomFromByteArray(fileBytes); } else { var filePath = HttpContext.Current.Server.MapPath(WebDavAppConfigManager.Instance.OfficeOnline.NewFilePath + Path.GetExtension(token.FilePath)); atom = new AtomFromByteArray(File.ReadAllBytes(filePath)); } Cobalt.Metrics o1; cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, atom, out o1); cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); Add(token.FilePath, cobaltFile); return cobaltFile; }
private CobaltFile CreateCobaltFile(DisposalEscrow disposalEscrow, bool isNewFile) { if (CobaltStore.partitionNames == null) { Dictionary <Guid, string> dictionary = new Dictionary <Guid, string>(); Dictionary <Guid, string> dictionary2 = dictionary; FilePartitionId content = FilePartitionId.Content; dictionary2.Add(content.GuidId, "C"); Dictionary <Guid, string> dictionary3 = dictionary; FilePartitionId coauthMetadata = FilePartitionId.CoauthMetadata; dictionary3.Add(coauthMetadata.GuidId, "CAM"); Dictionary <Guid, string> dictionary4 = dictionary; FilePartitionId o14EditorsTable = FilePartitionId.O14EditorsTable; dictionary4.Add(o14EditorsTable.GuidId, "O14E"); Dictionary <Guid, string> dictionary5 = dictionary; FilePartitionId wordWacConvertedDocument = FilePartitionId.WordWacConvertedDocument; dictionary5.Add(wordWacConvertedDocument.GuidId, "WWCD"); Dictionary <Guid, string> dictionary6 = dictionary; FilePartitionId wordWacUpdate = FilePartitionId.WordWacUpdate; dictionary6.Add(wordWacUpdate.GuidId, "WWU"); CobaltStore.partitionNames = dictionary; } CobaltFilePartitionConfig value = new CobaltFilePartitionConfig { PartitionId = new FilePartitionId?(FilePartitionId.Content), HostBlobStore = this.contentBlobStore, Schema = 2, IsNewFile = isNewFile }; CobaltFilePartitionConfig value2 = new CobaltFilePartitionConfig { PartitionId = new FilePartitionId?(FilePartitionId.CoauthMetadata), HostBlobStore = this.metadataBlobStore, Schema = 2, IsNewFile = isNewFile }; CobaltFilePartitionConfig value3 = new CobaltFilePartitionConfig { PartitionId = new FilePartitionId?(FilePartitionId.O14EditorsTable), HostBlobStore = this.editorTableBlobStore, Schema = 2, IsNewFile = isNewFile }; CobaltFilePartitionConfig value4 = new CobaltFilePartitionConfig { PartitionId = new FilePartitionId?(FilePartitionId.WordWacConvertedDocument), HostBlobStore = this.convertedDocumentBlobStore, Schema = 2, IsNewFile = isNewFile }; CobaltFilePartitionConfig value5 = new CobaltFilePartitionConfig { PartitionId = new FilePartitionId?(FilePartitionId.WordWacUpdate), HostBlobStore = this.updateBlobStore, Schema = 2, IsNewFile = isNewFile }; return(new CobaltFile(disposalEscrow, new Dictionary <FilePartitionId, CobaltFilePartitionConfig> { { FilePartitionId.Content, value }, { FilePartitionId.CoauthMetadata, value2 }, { FilePartitionId.O14EditorsTable, value3 }, { FilePartitionId.WordWacConvertedDocument, value4 }, { FilePartitionId.WordWacUpdate, value5 } }, new CobaltServerLockingStore(this), null)); }
public void ProcessRequest(Stream requestStream, Stream responseStream, Action <Enum, string> logDetail) { if (this.permanentException != null) { throw new CobaltStore.OrphanedCobaltStoreException(string.Format("The attachment is no longer available for CobaltStore {0}.", this.correlationId), this.permanentException); } try { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); if (!Monitor.TryEnter(this.synchronizationObject, TimeSpan.FromSeconds(15.0))) { throw new Exception("Unable to acquire CobaltStore lock."); } stopwatch.Stop(); logDetail(WacRequestHandlerMetadata.LockWaitTime, stopwatch.ElapsedMilliseconds.ToString()); using (DisposalEscrow disposalEscrow = new DisposalEscrow("CobaltStore.ProcessRequest")) { using (Stream stream = new MemoryStream(65536)) { requestStream.CopyTo(stream, 65536); stream.Position = 0L; logDetail(WacRequestHandlerMetadata.CobaltRequestLength, stream.Length.ToString()); CobaltFile cobaltFile = this.CreateCobaltFile(disposalEscrow, false); this.SaveDiagnosticDocument(cobaltFile, "BeforeRoundTrip.bin"); this.SaveDiagnosticStream(requestStream, "Request.xml"); using (DisposableAtomFromStream disposableAtomFromStream = new DisposableAtomFromStream(stream)) { Roundtrip roundtrip = cobaltFile.CobaltEndpoint.CreateRoundtrip(); bool exceptionThrown = false; Atom atom = null; Stopwatch stopwatch2 = new Stopwatch(); stopwatch2.Start(); try { object obj; ProtocolVersion protocolVersion; roundtrip.DeserializeInputFromProtocol(disposableAtomFromStream, ref obj, ref protocolVersion); roundtrip.Execute(); cobaltFile.CommitChanges(); atom = roundtrip.SerializeOutputToProtocol(1, obj, null); } catch (Exception) { exceptionThrown = true; throw; } finally { stopwatch2.Stop(); logDetail(WacRequestHandlerMetadata.CobaltTime, stopwatch2.ElapsedMilliseconds.ToString()); this.LogBlobStoreMetrics(logDetail, cobaltFile); this.LogRequestDetails(logDetail, roundtrip, exceptionThrown); } this.UpdateEditorCount(roundtrip.RequestBatch); this.SaveDiagnosticDocument(cobaltFile, "AfterRoundTrip.bin"); atom.CopyTo(responseStream); logDetail(WacRequestHandlerMetadata.CobaltResponseLength, atom.Length.ToString()); if (this.diagnosticsEnabled) { using (MemoryStream memoryStream = new MemoryStream()) { atom.CopyTo(memoryStream); this.SaveDiagnosticStream(memoryStream, "Response.xml"); } } } } } } finally { if (Monitor.IsEntered(this.synchronizationObject)) { Monitor.Exit(this.synchronizationObject); } } }
/// <summary> /// Creates a new desktop with minimal rights. /// </summary> /// <param name="tracer">A tracer instance.</param> /// <returns>The desktop instance.</returns> public static Desktop Create(ITracer tracer, string mandatoryLevelSacl) { using (var disposalEscrow = new DisposalEscrow()) using (Desktop currentDesktop = Desktop.GetCurrent()) { try { string name = "sbox" + DateTime.UtcNow.Ticks; tracer.Trace(nameof(Desktop), "Creating desktop '{0}'", name); SECURITY_ATTRIBUTES securityAttributes = null; if (mandatoryLevelSacl != null) { tracer.Trace(nameof(Desktop), "Generating security attributes for '{0}'", mandatoryLevelSacl); // If a security descriptor (in SDDL form) was provided convert it to binary form and then marshal // it into native memory to that we can pass it in to the native method. var rawSecurityDescriptor = new RawSecurityDescriptor(mandatoryLevelSacl); var binaryForm = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(binaryForm, 0 /* offset */); var nativeBinaryForm = disposalEscrow.Add(new SafeHGlobalBuffer(binaryForm.Length)); Marshal.Copy(binaryForm, 0 /* startIndex */, nativeBinaryForm.DangerousGetHandle(), binaryForm.Length); securityAttributes = new SECURITY_ATTRIBUTES { lpSecurityDescriptor = nativeBinaryForm.DangerousGetHandle() }; } // Since we're creating the desktop we'll ask for all rights so that we have the ability to modify security as // required. Since the created desktop will be referenced by name when creating the process this will not impact // the security of the desktop. IntPtr unsafeDesktopHandle = Methods.CreateDesktop( name, device: null, deviceMode: null, flags: 0, accessMask: DESKTOP_RIGHTS.GENERIC_ALL, attributes: securityAttributes); if (unsafeDesktopHandle == IntPtr.Zero) { throw new SandboxException( $"Unable to create new desktop", new Win32Exception()); } tracer.Trace(nameof(Desktop), "Desktop successfully created"); return(new Desktop(unsafeDesktopHandle, ownsHandle: true) { Name = name, }); } finally { // Since CreateDesktop automatically switches to the new desktop we need to make sure that we switch back // to the original one. currentDesktop.MakeCurrent(); } } }
public CobaltSession(string sessionId, string filePath, string login = "******", string name = "Anonymous", string email = "", bool isAnonymous = true) : base(sessionId, filePath, login, name, email, isAnonymous) { m_disposal = new DisposalEscrow(m_sessionId); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = true; content.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".Content"); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig(); coauth.IsNewFile = true; coauth.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".CoauthMetadata"); coauth.cellSchemaIsGenericFda = false; coauth.CellStorageConfig = new CellStorageConfig(); coauth.Schema = CobaltFilePartition.Schema.ShreddedCobalt; coauth.PartitionId = FilePartitionId.CoauthMetadata; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = true; wacupdate.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".WordWacUpdate"); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary <FilePartitionId, CobaltFilePartitionConfig> partitionConfs = new Dictionary <FilePartitionId, CobaltFilePartitionConfig>(); partitionConfs.Add(FilePartitionId.Content, content); partitionConfs.Add(FilePartitionId.WordWacUpdate, wacupdate); partitionConfs.Add(FilePartitionId.CoauthMetadata, coauth); m_cobaltFile = new CobaltFile(m_disposal, partitionConfs, new CobaltHostLockingStore(this), null); if (m_fileinfo.Exists) { String appdata_path = Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData); appdata_path = Path.Combine(appdata_path, @"WopiCobaltHost"); if (!Directory.Exists(appdata_path)) { Directory.CreateDirectory(appdata_path); } String cache_file = Path.Combine(appdata_path, m_fileinfo.Name); if (File.Exists(cache_file)) { File.Delete(cache_file); } File.Copy(m_fileinfo.FullName, cache_file, true); var file_atom = FileAtom.FromExisting(cache_file, m_disposal); //if want to avoid temp file, you can use memory Atom below //MemoryStream ms = new MemoryStream(); //using (FileStream fileStream = m_fileinfo.OpenRead()) //{ // fileStream.CopyTo(ms); //} //var src_atom = new AtomFromByteArray(ms.ToArray()); Cobalt.Metrics o1; m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, file_atom, out o1); m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } }
/// <summary> /// 查看Session /// </summary> /// <param name="sessionId">当前session Id</param> /// <param name="filePath">文件路径</param> /// <param name="login">当前登录用户</param> /// <param name="name">文件所属人(作者)</param> /// <param name="isAnonymous">是否匿名</param> public CobaltSession(string sessionId, string filePath, string login = "******", string name = "Anonymous", bool isAnonymous = true) : base(sessionId, filePath, login, name, isAnonymous) { m_disposal = new DisposalEscrow(m_sessionId); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = true; content.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".Content"); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig coauth = new CobaltFilePartitionConfig(); coauth.IsNewFile = true; coauth.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".CoauthMetadata"); coauth.cellSchemaIsGenericFda = false; coauth.CellStorageConfig = new CellStorageConfig(); coauth.Schema = CobaltFilePartition.Schema.ShreddedCobalt; coauth.PartitionId = FilePartitionId.CoauthMetadata; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = true; wacupdate.HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), m_disposal, m_sessionId + @".WordWacUpdate"); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary <FilePartitionId, CobaltFilePartitionConfig> partitionConfs = new Dictionary <FilePartitionId, CobaltFilePartitionConfig>(); partitionConfs.Add(FilePartitionId.Content, content); partitionConfs.Add(FilePartitionId.WordWacUpdate, wacupdate); partitionConfs.Add(FilePartitionId.CoauthMetadata, coauth); m_cobaltFile = new CobaltFile(m_disposal, partitionConfs, new CobaltHostLockingStore(this), null); if (m_fileinfo.Exists) { //String appdata_path = Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData); String appdata_path = @"C:\temp"; appdata_path = Path.Combine(appdata_path, @"WopiCobaltHost"); logger.Info($"临时文件家路径:{appdata_path}"); if (!Directory.Exists(appdata_path)) { Directory.CreateDirectory(appdata_path); } String cache_file = Path.Combine(appdata_path, m_fileinfo.Name); if (File.Exists(cache_file)) { File.Delete(cache_file); } File.Copy(m_fileinfo.FullName, cache_file, true); var file_atom = FileAtom.FromExisting(cache_file, m_disposal); Cobalt.Metrics o1; m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, file_atom, out o1); m_cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); } }
private SafeTokenHandle GetRestrictedToken() { if (this.restrictedTokenHandle == null) { using (var localDisposalEscrow = new DisposalEscrow()) { // The first step in creating a restricted token is to enumerate the existing one and decide which of // the SIDs we want to deny, and which of the SIDs we want to restrict. For our purposes we want: // // DENY all except: // CurrentUser // Everyone // Users // Interactive // Logon // // RESTRICT only: // CurrentUser // Everyone // Users // Logon // Restricted var sidsToDeny = new List <SID_AND_ATTRIBUTES>(); var sidsToRestrict = new List <SID_AND_ATTRIBUTES>(); foreach (IdentityReference identityReference in this.identityProvider.CurrentUser.Groups) { var securityIdentifier = (SecurityIdentifier)identityReference.Translate(typeof(SecurityIdentifier)); if (securityIdentifier.Equals(this.identityProvider.EveryoneSid) || securityIdentifier.Equals(this.identityProvider.UsersSid)) { // Add the group to the restricted list if it's one of the special groups we want to allow. sidsToRestrict.Add( RestrictedProcessProtection.ConvertSecurityIdentifierToSidAndAttributes(securityIdentifier, localDisposalEscrow)); } else if (!securityIdentifier.Equals(this.identityProvider.InteractiveSid)) { // Otherwise add the group to the deny list, but special case the Interactive SID which // shouldn't be denied and also not restricted. sidsToDeny.Add( RestrictedProcessProtection.ConvertSecurityIdentifierToSidAndAttributes(securityIdentifier, localDisposalEscrow)); } } // There are a set of non-group SIDs that we want to always restrict and never deny, so add them to // the appropriate lists. sidsToRestrict.Add( RestrictedProcessProtection.ConvertSecurityIdentifierToSidAndAttributes( this.identityProvider.CurrentUserSid, localDisposalEscrow)); sidsToRestrict.Add( RestrictedProcessProtection.ConvertSecurityIdentifierToSidAndAttributes( this.identityProvider.LogonSid, localDisposalEscrow)); sidsToRestrict.Add( RestrictedProcessProtection.ConvertSecurityIdentifierToSidAndAttributes( this.identityProvider.RestrictedSid, localDisposalEscrow)); this.tracer.Trace(nameof(RestrictedProcessProtection), "Creating restricted token"); // Now that we have all the SIDs in the correct buckets we can call the native method to generate our // new token. SafeTokenHandle newTokenHandle; if (!Methods.CreateRestrictedToken( localDisposalEscrow.Add(new SafeTokenHandle(this.identityProvider.CurrentUser.Token, ownsHandle: false)), RESTRICTED_TOKEN_FLAGS.DISABLE_MAX_PRIVILEGE, (uint)sidsToDeny.Count, sidsToDeny.ToArray(), 0 /* deletePrivilegeCount */, null /* privilegesToDelete */, (uint)sidsToRestrict.Count, sidsToRestrict.ToArray(), out newTokenHandle)) { throw new SandboxException( "Unable to create restricted token", new Win32Exception()); } // We'll add the token here in case something breaks, but we'll remove it before we return the token at // the end of this method. localDisposalEscrow.Add(newTokenHandle); this.tracer.Trace(nameof(RestrictedProcessProtection), "Adding mandatory low SID"); // Create the low integrity SID. SafeSecurityIdentifier restrictedSecurityIdentifierNative; if (!Methods.AllocateAndInitializeSid( ref Constants.SECURITY_MANDATORY_LABEL_AUTHORITY, 1 /* nSubAuthorityCount */, (int)SECURITY_MANDATOR_RID.LOW, 0 /* dwSubAuthority1 */, 0 /* dwSubAuthority2 */, 0 /* dwSubAuthority3 */, 0 /* dwSubAuthority4 */, 0 /* dwSubAuthority5 */, 0 /* dwSubAuthority6 */, 0 /* dwSubAuthority7 */, out restrictedSecurityIdentifierNative)) { throw new SandboxException( "Unable to allocate and initialize low integrity SID", new Win32Exception()); } // Set the integrity level in the access token to low using the low integrity SID we just created. TOKEN_MANDATORY_LABEL managedTokenMandatoryLabel; managedTokenMandatoryLabel.Label.Attributes = SID_ATTRIBUTES.SE_GROUP_INTEGRITY; managedTokenMandatoryLabel.Label.Sid = restrictedSecurityIdentifierNative.DangerousGetHandle(); var nativeTokenMandatoryLabel = localDisposalEscrow.Add(new SafeHGlobalBuffer(Marshal.SizeOf(managedTokenMandatoryLabel))); Marshal.StructureToPtr(managedTokenMandatoryLabel, nativeTokenMandatoryLabel.DangerousGetHandle(), false); if (!Methods.SetTokenInformation( newTokenHandle, TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, nativeTokenMandatoryLabel.DangerousGetHandle(), nativeTokenMandatoryLabel.Size + Methods.GetLengthSid(restrictedSecurityIdentifierNative.DangerousGetHandle()))) { throw new SandboxException( "Unable to set token integrity level", new Win32Exception()); } this.tracer.Trace(nameof(RestrictedProcessProtection), "Granting login SID access to token"); // Now modify the access token to set the DACL so that the Logon SID has appropriate access to any // processes started using the token. Without this things mostly work, but the process will be // restricted in ways that .NET doesn't like (E.g. it's not possible to get the token associated with // the process) var defaultDaclDescriptor = new RawSecurityDescriptor( string.Format( RestrictedProcessProtection.DefaultDaclTemplate, this.identityProvider.LogonSid.Value)); var managedDefaultDacl = new byte[defaultDaclDescriptor.DiscretionaryAcl.BinaryLength]; defaultDaclDescriptor.DiscretionaryAcl.GetBinaryForm(managedDefaultDacl, 0 /* offset */); var nativeDefaultDacl = localDisposalEscrow.Add(new SafeHGlobalBuffer(managedDefaultDacl.Length)); Marshal.Copy( managedDefaultDacl, 0 /* startIndex */, nativeDefaultDacl.DangerousGetHandle(), managedDefaultDacl.Length); TOKEN_DEFAULT_DACL managedTokenDefaultDacl; managedTokenDefaultDacl.DefaultDacl = nativeDefaultDacl.DangerousGetHandle(); var nativeTokenDefaultDacl = localDisposalEscrow.Add(new SafeHGlobalBuffer(Marshal.SizeOf(managedTokenDefaultDacl))); Marshal.StructureToPtr(managedTokenDefaultDacl, nativeTokenDefaultDacl.DangerousGetHandle(), false /* fDeleteOld */); if (!Methods.SetTokenInformation( newTokenHandle, TOKEN_INFORMATION_CLASS.TokenDefaultDacl, nativeTokenDefaultDacl.DangerousGetHandle(), nativeTokenDefaultDacl.Size)) { throw new SandboxException( "Unable to set the DACL to give the Logon SID access to the process", new Win32Exception()); } this.disposalEscrow.Transfer(localDisposalEscrow, newTokenHandle); this.restrictedTokenHandle = newTokenHandle; } } return(this.restrictedTokenHandle); }
public CobaltFile Create(int accessTokenId) { var disposal = new DisposalEscrow(accessTokenId.ToString(CultureInfo.InvariantCulture)); var content = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".Content"), cellSchemaIsGenericFda = true, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.Content }; var coauth = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".CoauthMetadata"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.CoauthMetadata }; var wacupdate = new CobaltFilePartitionConfig { IsNewFile = true, HostBlobStore = new TemporaryHostBlobStore(new TemporaryHostBlobStore.Config(), disposal, accessTokenId + @".WordWacUpdate"), cellSchemaIsGenericFda = false, CellStorageConfig = new CellStorageConfig(), Schema = CobaltFilePartition.Schema.ShreddedCobalt, PartitionId = FilePartitionId.WordWacUpdate }; var partitionConfs = new Dictionary <FilePartitionId, CobaltFilePartitionConfig> { { FilePartitionId.Content, content }, { FilePartitionId.WordWacUpdate, wacupdate }, { FilePartitionId.CoauthMetadata, coauth } }; var cobaltFile = new CobaltFile(disposal, partitionConfs, new CobaltHostLockingStore(), null); var token = _tokenManager.GetToken(accessTokenId); Atom atom; if (_webDavManager.FileExist(token.FilePath)) { var fileBytes = _webDavManager.GetFileBytes(token.FilePath); atom = new AtomFromByteArray(fileBytes); } else { var filePath = HttpContext.Current.Server.MapPath(WebDavAppConfigManager.Instance.OfficeOnline.NewFilePath + Path.GetExtension(token.FilePath)); atom = new AtomFromByteArray(File.ReadAllBytes(filePath)); } Cobalt.Metrics o1; cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, atom, out o1); cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); Add(token.FilePath, cobaltFile); return(cobaltFile); }