예제 #1
0
        public override void Close()
        {
            base.Close();
#endif
            if (MonoWorkarounds.IsRequired(10163) && m_bWrite)
            {
                try
                {
                    Stream s = this.BaseStream;
                    Type   t = s.GetType();
                    if (t.Name == "WebConnectionStream")
                    {
                        PropertyInfo pi = t.GetProperty("Request",
                                                        BindingFlags.Instance | BindingFlags.NonPublic);
                        if (pi != null)
                        {
                            WebRequest wr = (pi.GetValue(s, null) as WebRequest);
                            if (wr != null)
                            {
                                IOConnection.DisposeResponse(wr.GetResponse(), false);
                            }
                            else
                            {
                                Debug.Assert(false);
                            }
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }
        }
예제 #2
0
        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);

            IOConnection.ConfigureWebRequest(request);
            return(request);
        }
예제 #3
0
        public static byte[] ReadFile(IOConnectionInfo ioc)
        {
            Stream       sIn = null;
            MemoryStream ms  = null;

            try
            {
                sIn = IOConnection.OpenRead(ioc);
                if (sIn == null)
                {
                    return(null);
                }

                ms = new MemoryStream();
                MemUtil.CopyStream(sIn, ms);

                return(ms.ToArray());
            }
            catch (Exception) { }
            finally
            {
                if (sIn != null)
                {
                    sIn.Close();
                }
                if (ms != null)
                {
                    ms.Close();
                }
            }

            return(null);
        }
예제 #4
0
 public bool CanProbablyAccess()
 {
     if (IsLocalFile())
     {
         return(IOConnection.FileExists(this, false));                // Raises event
     }
     return(true);
 }
예제 #5
0
        private void CommitWriteTransaction()
        {
            bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if (!KeePassLibSD && !KeePassRT)
            FileSecurity bkSecurity    = null;
            bool         bEfsEncrypted = false;
#endif

            if (IOConnection.FileExists(m_iocBase))
            {
#if (!KeePassLibSD && !KeePassRT)
                if (m_iocBase.IsLocalFile())
                {
                    try
                    {
                        FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
                        bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);

                        DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
                        bkSecurity = File.GetAccessControl(m_iocBase.Path);

                        File.SetCreationTime(m_iocTemp.Path, tCreation);
                    }
                    catch (Exception) { Debug.Assert(false); }
                }
#endif

                IOConnection.DeleteFile(m_iocBase);
            }

            IOConnection.RenameFile(m_iocTemp, m_iocBase);

#if (!KeePassLibSD && !KeePassRT)
            if (m_iocBase.IsLocalFile())
            {
                try
                {
                    if (bEfsEncrypted)
                    {
                        try { File.Encrypt(m_iocBase.Path); }
                        catch (Exception) { Debug.Assert(false); }
                    }

                    if (bkSecurity != null)
                    {
                        File.SetAccessControl(m_iocBase.Path, bkSecurity);
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }
#endif

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(m_iocBase.Path, true);                           // Hide again
            }
        }
예제 #6
0
            // Throws on error
            public static LockFileInfo Create(IOConnectionInfo iocLockFile)
            {
                LockFileInfo lfi;
                Stream       s = null;

                try
                {
                    byte[] pbID    = CryptoRandom.Instance.GetRandomBytes(16);
                    string strTime = TimeUtil.SerializeUtc(DateTime.UtcNow);

                    lfi = new LockFileInfo(Convert.ToBase64String(pbID), strTime,
#if KeePassUAP
                                           EnvironmentExt.UserName, EnvironmentExt.MachineName,
                                           EnvironmentExt.UserDomainName);
#elif KeePassLibSD
                                           string.Empty, string.Empty, string.Empty);
#else
                                           Environment.UserName, Environment.MachineName,
                                           Environment.UserDomainName);
#endif

                    StringBuilder sb = new StringBuilder();
#if !KeePassLibSD
                    sb.AppendLine(LockFileHeader);
                    sb.AppendLine(lfi.ID);
                    sb.AppendLine(strTime);
                    sb.AppendLine(lfi.UserName);
                    sb.AppendLine(lfi.Machine);
                    sb.AppendLine(lfi.Domain);
#else
                    sb.Append(LockFileHeader + MessageService.NewLine);
                    sb.Append(lfi.ID + MessageService.NewLine);
                    sb.Append(strTime + MessageService.NewLine);
                    sb.Append(lfi.UserName + MessageService.NewLine);
                    sb.Append(lfi.Machine + MessageService.NewLine);
                    sb.Append(lfi.Domain + MessageService.NewLine);
#endif

                    byte[] pbFile = StrUtil.Utf8.GetBytes(sb.ToString());

                    s = IOConnection.OpenWrite(iocLockFile);
                    if (s == null)
                    {
                        throw new IOException(iocLockFile.GetDisplayName());
                    }
                    s.Write(pbFile, 0, pbFile.Length);
                }
                finally { if (s != null)
                          {
                              s.Close();
                          }
                }

                return(lfi);
            }
예제 #7
0
		public Stream OpenWrite()
		{
			if(!m_bTransacted) m_bMadeUnhidden = UrlUtil.UnhideFile(m_iocTemp.Path);
			else // m_bTransacted
			{
				try { IOConnection.DeleteFile(m_iocTemp); }
				catch(Exception) { }
			}

			return IOConnection.OpenWrite(m_iocTemp);
		}
예제 #8
0
            public static LockFileInfo Load(IOConnectionInfo iocLockFile)
            {
                Stream s = null;

                try
                {
                    s = IOConnection.OpenRead(iocLockFile);
                    if (s == null)
                    {
                        return(null);
                    }
                    StreamReader sr  = new StreamReader(s, StrUtil.Utf8);
                    string       str = sr.ReadToEnd();
                    sr.Close();
                    if (str == null)
                    {
                        Debug.Assert(false);
                        return(null);
                    }

                    str = StrUtil.NormalizeNewLines(str, false);
                    string[] v = str.Split('\n');
                    if ((v == null) || (v.Length < 6))
                    {
                        Debug.Assert(false);
                        return(null);
                    }

                    if (!v[0].StartsWith(LockFileHeader))
                    {
                        Debug.Assert(false);
                        return(null);
                    }
                    return(new LockFileInfo(v[1], v[2], v[3], v[4], v[5]));
                }
                catch (FileNotFoundException)
                {
                }
                catch (Exception)
                {
                    Debug.Assert(false);
                }
                finally
                {
                    if (s != null)
                    {
                        s.Close();
                    }
                }

                return(null);
            }
예제 #9
0
        public static byte[] ReadFile(IOConnectionInfo ioc)
        {
            try
            {
                using (Stream s = IOConnection.OpenRead(ioc))
                {
                    return(MemUtil.Read(s));
                }
            }
            catch (Exception) { Debug.Assert(false); }

            return(null);
        }
예제 #10
0
        public void Save(string strFile, PwGroup pgDataSource, Kdb4Format format,
                         IStatusLogger slLogger)
        {
            bool bMadeUnhidden = UrlUtil.UnhideFile(strFile);

            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);

            this.Save(IOConnection.OpenWrite(ioc), pgDataSource, format, slLogger);

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(strFile, true);                           // Hide again
            }
        }
예제 #11
0
        public Stream OpenWrite()
        {
            if (m_iocBase == null)
            {
                Debug.Assert(false); throw new ObjectDisposedException(null);
            }

            if (!m_bTransacted)
            {
                m_bMadeUnhidden |= UrlUtil.UnhideFile(m_iocTemp.Path);
            }

            return(IOConnection.OpenWrite(m_iocTemp));
        }
예제 #12
0
        private void CommitWriteTransaction()
        {
            bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if !KeePassLibSD
            FileSecurity bkSecurity = null;
#endif

            if (IOConnection.FileExists(m_iocBase))
            {
#if !KeePassLibSD
                if (m_iocBase.IsLocalFile())
                {
                    try
                    {
                        DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
                        bkSecurity = File.GetAccessControl(m_iocBase.Path);

                        File.SetCreationTime(m_iocTemp.Path, tCreation);
                    }
                    catch (Exception) { Debug.Assert(false); }
                }
#endif

                IOConnection.DeleteFile(m_iocBase);
            }

            IOConnection.RenameFile(m_iocTemp, m_iocBase);

#if !KeePassLibSD
            if (m_iocBase.IsLocalFile())
            {
                try
                {
                    if (bkSecurity != null)
                    {
                        File.SetAccessControl(m_iocBase.Path, bkSecurity);
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }
#endif

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(m_iocBase.Path, true);                           // Hide again
            }
        }
예제 #13
0
        private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc,
                                                  IOConnectionInfo ioc2, IOAccessType t)
        {
            if (ioc == null)
            {
                Debug.Assert(false); return;
            }
            // ioc2 may be null

            if (IOConnection.IOAccessPre != null)
            {
                IOConnectionInfo  ioc2Lcl = ((ioc2 != null) ? ioc2.CloneDeep() : null);
                IOAccessEventArgs e       = new IOAccessEventArgs(ioc.CloneDeep(), ioc2Lcl, t);
                IOConnection.IOAccessPre(null, e);
            }
        }
예제 #14
0
            public override void Close()
            {
                base.Close();

                WebRequest testReq = WebRequest.Create(ioc.Path);

                if (testReq is HttpWebRequest)
                {
                    RepeatWithDigestOnFail(ioc, req =>
                    {
                        req.Headers.Add("Translate: f");

                        if (method != null)
                        {
                            req.Method = method;
                        }
                        var data = this.ToArray();

                        using (Stream s = req.GetRequestStream())
                        {
                            s.Write(data, 0, data.Length);
                            req.GetResponse();
                            s.Close();
                        }
                    });
                }
                else
                {
                    try
                    {
                        uploadData(IOConnection.CreateWebClient(ioc, false));
                    }
                    catch (WebException ex)
                    {
                        //todo: does this make sense for FTP at all? Remove?
                        if ((ex.Response is HttpWebResponse) && (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.Unauthorized))
                        {
                            uploadData(IOConnection.CreateWebClient(ioc, true));
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            }
예제 #15
0
        private void Dispose(bool bDisposing)
        {
            if (m_iocLockFile == null)
            {
                return;
            }

            bool bFileDeleted = false;

            for (int r = 0; r < 5; ++r)
            {
                // if(!OwnLockFile()) { bFileDeleted = true; break; }

                try
                {
                    IOConnection.DeleteFile(m_iocLockFile);
                    bFileDeleted = true;
                }
                catch (Exception)
                {
                    Debug.Assert(false);
                }

                if (bFileDeleted)
                {
                    break;
                }

                if (bDisposing)
                {
                    Thread.Sleep(50);
                }
            }

            if (bDisposing && !bFileDeleted)
            {
                IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception
            }
            m_iocLockFile = null;
        }
예제 #16
0
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (disposing && MonoWorkarounds.IsRequired(10163) && m_bWrite &&
                !m_bDisposed)
            {
                try
                {
                    Stream s = this.BaseStream;
                    Type   t = s.GetType();
                    if (t.Name == "WebConnectionStream")
                    {
                        PropertyInfo pi = t.GetProperty("Request",
                                                        BindingFlags.Instance | BindingFlags.NonPublic);
                        if (pi != null)
                        {
                            WebRequest wr = (pi.GetValue(s, null) as WebRequest);
                            if (wr != null)
#if KeePassUWP
                            {
                                var task = wr.GetResponseAsync();
                                task.RunSynchronously();
                                var response = task.Result;
                                IOConnection.DisposeResponse(response, false);
                            }
#else
                            { IOConnection.DisposeResponse(wr.GetResponse(), false); }
#endif
                            else
                            {
                                Debug.Assert(false);
                            }
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                }
예제 #17
0
        private void Dispose(bool bDisposing)
        {
            if (m_iocLockFile == null)
            {
                return;
            }

            bool bFileDeleted = false;

            for (int r = 0; r < 5; ++r)
            {
                // if(!OwnLockFile()) { bFileDeleted = true; break; }

                try
                {
                    IOConnection.DeleteFile(m_iocLockFile);
                    bFileDeleted = true;
                }
                catch (Exception) { Debug.Assert(false); }

                if (bFileDeleted)
                {
                    break;
                }

                if (bDisposing)
                {
#if !FEATURE_TASKS
                    Thread.Sleep(50);
#else
                    System.Threading.Tasks.Task.Delay(50).ConfigureAwait(false).GetAwaiter().GetResult();
#endif
                }
            }

            // if(bDisposing && !bFileDeleted)
            //	IOConnection.DeleteFile(m_iocLockFile); // Possibly with exception

            m_iocLockFile = null;
        }
예제 #18
0
        private void Dispose(bool bDisposing)
        {
            m_iocBase = null;
            if (!bDisposing)
            {
                return;
            }

            try
            {
                foreach (IOConnectionInfo ioc in m_lToDelete)
                {
                    if (IOConnection.FileExists(ioc, false))
                    {
                        IOConnection.DeleteFile(ioc);
                    }
                }

                m_lToDelete.Clear();
            }
            catch (Exception) { Debug.Assert(false); }
        }
예제 #19
0
        private void CommitWriteTransaction()
        {
            bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if (!KeePassLibSD && !KeePassUAP)
            FileSecurity bkSecurity    = null;
            bool         bEfsEncrypted = false;
#endif

            if (g_bExtraSafe)
            {
                if (!IOConnection.FileExists(m_iocTemp))
                {
                    throw new FileNotFoundException(m_iocTemp.Path +
                                                    MessageService.NewLine + KLRes.FileSaveFailed);
                }
            }

            if (IOConnection.FileExists(m_iocBase))
            {
#if !KeePassLibSD
                if (m_iocBase.IsLocalFile())
                {
                    try
                    {
#if !KeePassUAP
                        FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
                        bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
#endif
                        DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
                        File.SetCreationTime(m_iocTemp.Path, tCreation);
#if !KeePassUAP
                        // May throw with Mono
                        bkSecurity = File.GetAccessControl(m_iocBase.Path);
#endif
                    }
                    catch (Exception) { Debug.Assert(NativeLib.IsUnix()); }
                }
#endif

                IOConnection.DeleteFile(m_iocBase);
            }

            IOConnection.RenameFile(m_iocTemp, m_iocBase);

#if (!KeePassLibSD && !KeePassUAP)
            if (m_iocBase.IsLocalFile())
            {
                try
                {
                    if (bEfsEncrypted)
                    {
                        try { File.Encrypt(m_iocBase.Path); }
                        catch (Exception) { Debug.Assert(false); }
                    }

                    if (bkSecurity != null)
                    {
                        File.SetAccessControl(m_iocBase.Path, bkSecurity);
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }
#endif

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(m_iocBase.Path, true);                           // Hide again
            }
        }
예제 #20
0
        /// <summary>
        /// Load a KDB file from a file.
        /// </summary>
        /// <param name="strFilePath">File to load.</param>
        /// <param name="kdbFormat">Format specifier.</param>
        /// <param name="slLogger">Status logger (optional).</param>
        public void Load(string strFilePath, Kdb4Format kdbFormat, IStatusLogger slLogger)
        {
            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);

            this.Load(IOConnection.OpenRead(ioc), kdbFormat, slLogger);
        }
예제 #21
0
        internal static void ConfigureWebRequest(WebRequest request,
                                                 IOConnectionInfo ioc)
        {
            if (request == null)
            {
                Debug.Assert(false); return;
            }                                                                // No throw

            IocProperties p = ((ioc != null) ? ioc.Properties : null);

            if (p == null)
            {
                Debug.Assert(false); p = new IocProperties();
            }

            IHasIocProperties ihpReq = (request as IHasIocProperties);

            if (ihpReq != null)
            {
                IocProperties pEx = ihpReq.IOConnectionProperties;
                if (pEx != null)
                {
                    p.CopyTo(pEx);
                }
                else
                {
                    ihpReq.IOConnectionProperties = p.CloneDeep();
                }
            }

            if (IsHttpWebRequest(request))
            {
                // WebDAV support
#if !KeePassUAP
                request.PreAuthenticate = true;                 // Also auth GET
#endif
                if (string.Equals(request.Method, WebRequestMethods.Http.Post,
                                  StrUtil.CaseIgnoreCmp))
                {
                    request.Method = WebRequestMethods.Http.Put;
                }

#if !KeePassUAP
                HttpWebRequest hwr = (request as HttpWebRequest);
                if (hwr != null)
                {
                    string strUA = p.Get(IocKnownProperties.UserAgent);
                    if (!string.IsNullOrEmpty(strUA))
                    {
                        hwr.UserAgent = strUA;
                    }
                }
                else
                {
                    Debug.Assert(false);
                }
#endif
            }
#if !KeePassUAP
            else if (IsFtpWebRequest(request))
            {
                FtpWebRequest fwr = (request as FtpWebRequest);
                if (fwr != null)
                {
                    bool?obPassive = p.GetBool(IocKnownProperties.Passive);
                    if (obPassive.HasValue)
                    {
                        fwr.UsePassive = obPassive.Value;
                    }
                }
                else
                {
                    Debug.Assert(false);
                }
            }
#endif

#if !KeePassUAP
            // Not implemented and ignored in Mono < 2.10
            try
            {
                request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
            }
            catch (NotImplementedException) { }
            catch (Exception) { Debug.Assert(false); }
#endif

            try
            {
                IWebProxy prx;
                if (GetWebProxy(out prx))
                {
                    request.Proxy = prx;
                }
            }
            catch (Exception) { Debug.Assert(false); }

#if !KeePassUAP
            long?olTimeout = p.GetLong(IocKnownProperties.Timeout);
            if (olTimeout.HasValue && (olTimeout.Value >= 0))
            {
                request.Timeout = (int)Math.Min(olTimeout.Value, (long)int.MaxValue);
            }

            bool?ob = p.GetBool(IocKnownProperties.PreAuth);
            if (ob.HasValue)
            {
                request.PreAuthenticate = ob.Value;
            }
#endif

            if (IOConnection.IOWebRequestPre != null)
            {
                IOWebRequestEventArgs e = new IOWebRequestEventArgs(request,
                                                                    ((ioc != null) ? ioc.CloneDeep() : null));
                IOConnection.IOWebRequestPre(null, e);
            }
        }
예제 #22
0
        /// <summary>
        /// Load a KDBX file.
        /// </summary>
        /// <param name="strFilePath">File to load.</param>
        /// <param name="fmt">Format.</param>
        /// <param name="slLogger">Status logger (optional).</param>
        public void Load(string strFilePath, KdbxFormat fmt, IStatusLogger slLogger)
        {
            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);

            Load(IOConnection.OpenRead(ioc), fmt, slLogger);
        }
예제 #23
0
        private void CommitWriteTransaction()
        {
            if (g_bExtraSafe)
            {
                if (!IOConnection.FileExists(m_iocTemp))
                {
                    throw new FileNotFoundException(m_iocTemp.Path +
                                                    MessageService.NewLine + KLRes.FileSaveFailed);
                }
            }

            bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if !KeePassUAP
            bool         bEfsEncrypted = false;
            FileSecurity bkSecurity    = null;
#endif
            DateTime?otCreation = null;

            bool bBaseExists = IOConnection.FileExists(m_iocBase);
            if (bBaseExists && m_iocBase.IsLocalFile())
            {
                // FileAttributes faBase = FileAttributes.Normal;
                try
                {
#if !KeePassUAP
                    FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
                    bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
                    try { if (bEfsEncrypted)
                          {
                              File.Decrypt(m_iocBase.Path);
                          }
                    }                                                                           // For TxF
                    catch (Exception) { Debug.Assert(false); }
#endif
                    otCreation = File.GetCreationTimeUtc(m_iocBase.Path);
#if !KeePassUAP
                    // May throw with Mono
                    bkSecurity = File.GetAccessControl(m_iocBase.Path);
#endif
                }
                catch (Exception) { Debug.Assert(NativeLib.IsUnix()); }

                // if((long)(faBase & FileAttributes.ReadOnly) != 0)
                //	throw new UnauthorizedAccessException();
            }

            if (!TxfMove())
            {
                if (bBaseExists)
                {
                    IOConnection.DeleteFile(m_iocBase);
                }
                IOConnection.RenameFile(m_iocTemp, m_iocBase);
            }

            try
            {
                // If File.GetCreationTimeUtc fails, it may return a
                // date with year 1601, and Unix times start in 1970,
                // so testing for 1971 should ensure validity;
                // https://msdn.microsoft.com/en-us/library/system.io.file.getcreationtimeutc.aspx
                if (otCreation.HasValue && (otCreation.Value.Year >= 1971))
                {
                    File.SetCreationTimeUtc(m_iocBase.Path, otCreation.Value);
                }

#if !KeePassUAP
                if (bEfsEncrypted)
                {
                    try { File.Encrypt(m_iocBase.Path); }
                    catch (Exception) { Debug.Assert(false); }
                }

                if (bkSecurity != null)
                {
                    File.SetAccessControl(m_iocBase.Path, bkSecurity);
                }
#endif
            }
            catch (Exception) { Debug.Assert(false); }

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(m_iocBase.Path, true);
            }
        }
예제 #24
0
        private void CommitWriteTransaction()
        {
            if (g_bExtraSafe)
            {
                if (!IOConnection.FileExists(m_iocTemp))
                {
                    throw new FileNotFoundException(m_iocTemp.Path +
                                                    MessageService.NewLine + KLRes.FileSaveFailed);
                }
            }

            bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if !KeePassUAP
            // 'All' includes 'Audit' (SACL), which requires SeSecurityPrivilege,
            // which we usually don't have and therefore get an exception;
            // trying to set 'Owner' or 'Group' can result in an
            // UnauthorizedAccessException; thus we restore 'Access' (DACL) only
            const AccessControlSections acs = AccessControlSections.Access;

            bool   bEfsEncrypted = false;
            byte[] pbSec         = null;
#endif
            DateTime?otCreation = null;

            bool bBaseExists = IOConnection.FileExists(m_iocBase);
            if (bBaseExists && m_iocBase.IsLocalFile())
            {
                // FileAttributes faBase = FileAttributes.Normal;
                try
                {
#if !KeePassUAP
                    FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
                    bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
                    try { if (bEfsEncrypted)
                          {
                              File.Decrypt(m_iocBase.Path);
                          }
                    }                                                                           // For TxF
                    catch (Exception) { Debug.Assert(false); }
#endif
                    otCreation = File.GetCreationTimeUtc(m_iocBase.Path);
#if !KeePassUAP
                    // May throw with Mono
                    FileSecurity sec = File.GetAccessControl(m_iocBase.Path, acs);
                    if (sec != null)
                    {
                        pbSec = sec.GetSecurityDescriptorBinaryForm();
                    }
#endif
                }
                catch (Exception) { Debug.Assert(NativeLib.IsUnix()); }

                // if((long)(faBase & FileAttributes.ReadOnly) != 0)
                //	throw new UnauthorizedAccessException();
            }

            if (!TxfMove())
            {
                if (bBaseExists)
                {
                    IOConnection.DeleteFile(m_iocBase);
                }
                IOConnection.RenameFile(m_iocTemp, m_iocBase);
            }
            else
            {
                Debug.Assert(pbSec != null);
            }                                                 // TxF success => NTFS => has ACL

            try
            {
                // If File.GetCreationTimeUtc fails, it may return a
                // date with year 1601, and Unix times start in 1970,
                // so testing for 1971 should ensure validity;
                // https://msdn.microsoft.com/en-us/library/system.io.file.getcreationtimeutc.aspx
                if (otCreation.HasValue && (otCreation.Value.Year >= 1971))
                {
                    File.SetCreationTimeUtc(m_iocBase.Path, otCreation.Value);
                }

#if !KeePassUAP
                if (bEfsEncrypted)
                {
                    try { File.Encrypt(m_iocBase.Path); }
                    catch (Exception) { Debug.Assert(false); }
                }

                // File.SetAccessControl(m_iocBase.Path, secPrev);
                // Directly calling File.SetAccessControl with the previous
                // FileSecurity object does not work; the binary form
                // indirection is required;
                // https://sourceforge.net/p/keepass/bugs/1738/
                // https://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol.aspx
                if ((pbSec != null) && (pbSec.Length != 0))
                {
                    FileSecurity sec = new FileSecurity();
                    sec.SetSecurityDescriptorBinaryForm(pbSec, acs);

                    File.SetAccessControl(m_iocBase.Path, sec);
                }
#endif
            }
            catch (Exception) { Debug.Assert(false); }

            if (bMadeUnhidden)
            {
                UrlUtil.HideFile(m_iocBase.Path, true);
            }
        }
예제 #25
0
		private void CommitWriteTransaction()
		{
			bool bMadeUnhidden = UrlUtil.UnhideFile(m_iocBase.Path);

#if (!KeePassLibSD && !KeePassUAP)
			FileSecurity bkSecurity = null;
			bool bEfsEncrypted = false;
#endif

			// Check that temporary file exists.
			if (!IOConnection.FileExists(m_iocTemp))
			{
				throw new FileNotFoundException("Temporary file disappeared before transaction completed.", 
				                                m_iocTemp.Path);
			}

			if (IOConnection.FileExists(m_iocBase))
			{
#if !KeePassLibSD
				if(m_iocBase.IsLocalFile())
				{
					try
					{
#if !KeePassUAP
						FileAttributes faBase = File.GetAttributes(m_iocBase.Path);
						bEfsEncrypted = ((long)(faBase & FileAttributes.Encrypted) != 0);
#endif
						DateTime tCreation = File.GetCreationTime(m_iocBase.Path);
						File.SetCreationTime(m_iocTemp.Path, tCreation);
#if !KeePassUAP
						// May throw with Mono
						bkSecurity = File.GetAccessControl(m_iocBase.Path);
#endif
					}
					catch(Exception) { Debug.Assert(NativeLib.IsUnix()); }
				}
#endif

				IOConnection.DeleteFile(m_iocBase);
			}

			IOConnection.RenameFile(m_iocTemp, m_iocBase);

#if (!KeePassLibSD && !KeePassUAP)
			if(m_iocBase.IsLocalFile())
			{
				try
				{
					if(bEfsEncrypted)
					{
						try { File.Encrypt(m_iocBase.Path); }
						catch(Exception) { Debug.Assert(false); }
					}

					if(bkSecurity != null)
						File.SetAccessControl(m_iocBase.Path, bkSecurity);
				}
				catch(Exception) { Debug.Assert(false); }
			}
#endif

			if(bMadeUnhidden) UrlUtil.HideFile(m_iocBase.Path, true); // Hide again
		}