Beispiel #1
0
 public static Stream OpenRead(IOConnectionInfo ioc)
 {
     return(OpenReadLocal(ioc));
 }
Beispiel #2
0
 private static Stream OpenReadLocal(IOConnectionInfo ioc)
 {
     return(new FileStream(ioc.Path, FileMode.Open, FileAccess.Read,
                           FileShare.Read));
 }
Beispiel #3
0
        public void ChangeDatabase(string fileName, bool closeCurrent)
        {
            if (closeCurrent && host.MainWindow.DocumentManager.ActiveDatabase != null && host.MainWindow.DocumentManager.ActiveDatabase.IsOpen)
            {
                host.MainWindow.DocumentManager.CloseDatabase(host.MainWindow.DocumentManager.ActiveDatabase);
            }

            KeePassLib.Serialization.IOConnectionInfo ioci = null;

            if (fileName != null && fileName.Length > 0)
            {
                ioci = new KeePassLib.Serialization.IOConnectionInfo();
                ioci.Path = fileName;
                ioci = CompleteConnectionInfoUsingMru(ioci);
            }

            // Set the current document / database to be the one we've been asked to display (may already be the case)
            // This is because the minimise/restore trick utilised a few frames later prompts KeePass into raising an
            // "enter key" dialog for the currently active database. This little check makes sure that the user sees
            // the database they've asked for first (assuming the database they want is already open but locked)
            // We can't stop an unneccessary prompt being seen if the user has asked for a new database to be opened
            // and the current workspace is locked
            //
            // We do this regardless of whether the DB is already open or locked
            //
            //TODO: Need to verify this works OK with unusual circumstances like one DB open but others locked
            if (ioci != null)
                foreach (PwDocument doc in host.MainWindow.DocumentManager.Documents)
                    if (doc.LockedIoc.Path == fileName ||
                        (doc.Database.IsOpen && doc.Database.IOConnectionInfo.Path == fileName))
                        host.MainWindow.DocumentManager.ActiveDocument = doc;

            // Going to take a new approach for a bit to see how it works out...
            //
            // before explicitly asking user to log into the correct DB we'll set up a "fake" document in KeePass
            // in the hope that the minimise/restore trick will get KeePass to prompt the user on our behalf
            // (regardless of state of existing documents and newly requested document)
            if (ioci != null
                && !(host.MainWindow.DocumentManager.ActiveDocument.Database.IsOpen && host.MainWindow.DocumentManager.ActiveDocument.Database.IOConnectionInfo.Path == fileName)
                && !(!host.MainWindow.DocumentManager.ActiveDocument.Database.IsOpen && host.MainWindow.DocumentManager.ActiveDocument.LockedIoc.Path == fileName))
            {
                PwDocument doc = host.MainWindow.DocumentManager.CreateNewDocument(true);
                //IOConnectionInfo ioci = new IOConnectionInfo();
                //ioci.Path = fileName;
                doc.LockedIoc = ioci;
            }

            // NB: going to modify implementation of the following function call so that only KeePass initiates the prompt (need to verify cross-platform, etc. even if it seems to work on win7x64)
            // if it works on some platforms, I will make it work on all platforms that support it and fall back to the old clunky method for others.
            host.MainWindow.BeginInvoke((MethodInvoker)delegate { promptUserToOpenDB(ioci); });
            return;
        }
Beispiel #4
0
        private static IOWebClient CreateWebClient(IOConnectionInfo ioc, bool digestAuth)
        {
            PrepareWebAccess();

            IOWebClient wc = new IOWebClient();

            ConfigureWebClient(wc);

            if ((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
            {
                //set the credentials without a cache (in case the cache below fails:

                //check for backslash to determine whether we need to specify the domain:
                int backslashPos = ioc.UserName.IndexOf("\\", StringComparison.Ordinal);
                if (backslashPos > 0)
                {
                    string domain = ioc.UserName.Substring(0, backslashPos);
                    string user   = ioc.UserName.Substring(backslashPos + 1);
                    wc.Credentials = new NetworkCredential(user, ioc.Password, domain);
                }
                else
                {
                    wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
                }


                if (digestAuth)
                {
                    //try to use the credential cache to access with Digest support:
                    try
                    {
                        var credentialCache = new CredentialCache();

                        credentialCache.Add(
                            new Uri(new Uri(ioc.Path).GetLeftPart(UriPartial.Authority)),
                            "Digest",
                            new NetworkCredential(ioc.UserName, ioc.Password)
                            );

                        credentialCache.Add(
                            new Uri(new Uri(ioc.Path).GetLeftPart(UriPartial.Authority)),
                            "NTLM",
                            new NetworkCredential(ioc.UserName, ioc.Password)
                            );


                        wc.Credentials = credentialCache;
                    } catch (NotImplementedException e)
                    {
                        Kp2aLog.Log(e.ToString());
                    } catch (Exception e)
                    {
                        Kp2aLog.LogUnexpectedError(e);
                        Debug.Assert(false);
                    }
                }
            }
            else if (NativeLib.IsUnix())            // Mono requires credentials
            {
                wc.Credentials = new NetworkCredential("anonymous", string.Empty);
            }

            return(wc);
        }
Beispiel #5
0
 public FileTransactionEx(IOConnectionInfo iocBaseFile) :
     this(iocBaseFile, true)
 {
 }
Beispiel #6
0
 public FileTransactionEx(IOConnectionInfo iocBaseFile)
 {
     Initialize(iocBaseFile, true);
 }
 public IOWebClient(IOConnectionInfo ioc) : base()
 {
     m_ioc = ioc;
 }
Beispiel #8
0
        private void Initialize(IOConnectionInfo iocBaseFile, bool bTransacted)
        {
            if (iocBaseFile == null)
            {
                throw new ArgumentNullException("iocBaseFile");
            }

            m_bTransacted = bTransacted;
            m_iocBase     = iocBaseFile.CloneDeep();

            string strPath = m_iocBase.Path;

            if (m_iocBase.IsLocalFile())
            {
                try
                {
                    if (File.Exists(strPath))
                    {
                        // Symbolic links are realized via reparse points;
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365503.aspx
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680.aspx
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365006.aspx
                        // Performing a file transaction on a symbolic link
                        // would delete/replace the symbolic link instead of
                        // writing to its target
                        FileAttributes fa = File.GetAttributes(strPath);
                        if ((long)(fa & FileAttributes.ReparsePoint) != 0)
                        {
                            m_bTransacted = false;
                        }
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }

#if !KeePassUAP
            // Prevent transactions for FTP URLs under .NET 4.0 in order to
            // avoid/workaround .NET bug 621450:
            // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
            if (strPath.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
                (Environment.Version.Major >= 4) && !NativeLib.IsUnix())
            {
                m_bTransacted = false;
            }
#endif

            foreach (KeyValuePair <string, bool> kvp in g_dEnabled)
            {
                if (strPath.StartsWith(kvp.Key, StrUtil.CaseIgnoreCmp))
                {
                    m_bTransacted = kvp.Value;
                    break;
                }
            }

            if (m_bTransacted)
            {
                m_iocTemp       = m_iocBase.CloneDeep();
                m_iocTemp.Path += StrTempSuffix;
            }
            else
            {
                m_iocTemp = m_iocBase;
            }
        }
 private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc, IOAccessType t)
 {
     RaiseIOAccessPreEvent(ioc, null, t);
 }
        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);
            }
        }
 /// <summary>
 /// Determines whether the database pointed to by the specified ioc should be (de)serialised in default (xml) or protocol buffers format.
 /// </summary>
 public static KdbxFormat GetFormatToUse(IOConnectionInfo ioc)
 {
     // If the filename ends in .kdbp, use ProtocolBuffers format.
     return(UrlUtil.GetExtension(UrlUtil.GetFileName(ioc.Path)).Equals(KdbpFile.FileNameExtension, StringComparison.OrdinalIgnoreCase) ? KdbxFormat.ProtocolBuffers : KdbxFormat.Default);
 }
Beispiel #12
0
 public UploadOnCloseMemoryStream(IOConnectionInfo _ioc, Uri _destinationFilePath)
 {
     this.ioc    = _ioc;
     this.method = null;
     this.destinationFilePath = _destinationFilePath;
 }
Beispiel #13
0
 public UploadOnCloseMemoryStream(IOConnectionInfo _ioc, string _method, Uri _destinationFilePath)
 {
     ioc         = _ioc;
     this.method = _method;
     this.destinationFilePath = _destinationFilePath;
 }
Beispiel #14
0
 public static Stream OpenWrite(IOConnectionInfo ioc)
 {
     return(OpenWriteLocal(ioc));
 }
        private static void PrepareWebAccess(IOConnectionInfo ioc)
        {
#if !KeePassUAP && !NETSTANDARD2_0
            IocProperties p = ((ioc != null) ? ioc.Properties : null);
            if (p == null)
            {
                Debug.Assert(false); p = new IocProperties();
            }

            try
            {
                if (m_bSslCertsAcceptInvalid)
                {
                    ServicePointManager.ServerCertificateValidationCallback =
                        IOConnection.AcceptCertificate;
                }
                else
                {
                    ServicePointManager.ServerCertificateValidationCallback = null;
                }
            }
            catch (Exception) { Debug.Assert(false); }

            try
            {
                SecurityProtocolType spt = (SecurityProtocolType.Ssl3 |
                                            SecurityProtocolType.Tls);

                // The flags Tls11 and Tls12 in SecurityProtocolType have been
                // introduced in .NET 4.5 and must not be set when running under
                // older .NET versions (otherwise an exception is thrown)
                Type     tSpt = typeof(SecurityProtocolType);
                string[] vSpt = Enum.GetNames(tSpt);
                foreach (string strSpt in vSpt)
                {
                    if (strSpt.Equals("Tls11", StrUtil.CaseIgnoreCmp) ||
                        strSpt.Equals("Tls12", StrUtil.CaseIgnoreCmp) ||
                        strSpt.Equals("Tls13", StrUtil.CaseIgnoreCmp))
                    {
                        spt |= (SecurityProtocolType)Enum.Parse(tSpt, strSpt, true);
                    }
                }

                ServicePointManager.SecurityProtocol = spt;
            }
            catch (Exception) { Debug.Assert(false); }

            try
            {
                bool bCurCont = ServicePointManager.Expect100Continue;
                if (!m_obDefaultExpect100Continue.HasValue)
                {
                    Debug.Assert(bCurCont);                     // Default should be true
                    m_obDefaultExpect100Continue = bCurCont;
                }

                bool bNewCont = m_obDefaultExpect100Continue.Value;
                bool?ob       = p.GetBool(IocKnownProperties.Expect100Continue);
                if (ob.HasValue)
                {
                    bNewCont = ob.Value;
                }

                if (bNewCont != bCurCont)
                {
                    ServicePointManager.Expect100Continue = bNewCont;
                }
            }
            catch (Exception) { Debug.Assert(false); }
#endif
        }
Beispiel #16
0
 private static Stream OpenWriteLocal(IOConnectionInfo ioc)
 {
     return(new FileStream(ioc.Path, FileMode.Create, FileAccess.Write,
                           FileShare.None));
 }
        public static Stream OpenRead(IOConnectionInfo ioc)
        {
            RaiseIOAccessPreEvent(ioc, IOAccessType.Read);

            return(OpenReadLocal(ioc));
        }
Beispiel #18
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, KdbxFormat kdbFormat, IStatusLogger slLogger)
        {
            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFilePath);

            Load(IOConnection.OpenRead(ioc), kdbFormat, slLogger);
        }
        public static Stream OpenWrite(IOConnectionInfo ioc)
        {
            RaiseIOAccessPreEvent(ioc, IOAccessType.Write);

            return(OpenWriteLocal(ioc));
        }
Beispiel #20
0
        public FileTransactionEx(IOConnectionInfo iocBaseFile, bool bTransacted)
        {
            if (iocBaseFile == null)
            {
                throw new ArgumentNullException("iocBaseFile");
            }

            m_bTransacted = bTransacted;

            m_iocBase = iocBaseFile.CloneDeep();
            if (m_iocBase.IsLocalFile())
            {
                m_iocBase.Path = UrlUtil.GetShortestAbsolutePath(m_iocBase.Path);
            }

            string strPath = m_iocBase.Path;

            if (m_iocBase.IsLocalFile())
            {
                try
                {
                    if (File.Exists(strPath))
                    {
                        // Symbolic links are realized via reparse points;
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365503.aspx
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365680.aspx
                        // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365006.aspx
                        // Performing a file transaction on a symbolic link
                        // would delete/replace the symbolic link instead of
                        // writing to its target
                        FileAttributes fa = File.GetAttributes(strPath);
                        if ((long)(fa & FileAttributes.ReparsePoint) != 0)
                        {
                            m_bTransacted = false;
                        }
                    }
                    else
                    {
                        // If the base and the temporary file are in different
                        // folders and the base file doesn't exist (i.e. we can't
                        // backup the ACL), a transaction would cause the new file
                        // to have the default ACL of the temporary folder instead
                        // of the one of the base folder; therefore, we don't use
                        // a transaction when the base file doesn't exist (this
                        // also results in other applications monitoring the folder
                        // to see one file creation only)
                        m_bTransacted = false;
                    }
                }
                catch (Exception) { Debug.Assert(false); }
            }

#if !KeePassUAP && !KeePassUWP
            // Prevent transactions for FTP URLs under .NET 4.0 in order to
            // avoid/workaround .NET bug 621450:
            // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
            if (strPath.StartsWith("ftp:", StrUtil.CaseIgnoreCmp) &&
                (Environment.Version.Major >= 4) && !NativeLib.IsUnix())
            {
                m_bTransacted = false;
            }
#endif

            foreach (KeyValuePair <string, bool> kvp in g_dEnabled)
            {
                if (strPath.StartsWith(kvp.Key, StrUtil.CaseIgnoreCmp))
                {
                    m_bTransacted = kvp.Value;
                    break;
                }
            }

            if (m_bTransacted)
            {
                m_iocTemp       = m_iocBase.CloneDeep();
                m_iocTemp.Path += StrTempSuffix;

                TxfPrepare();                 // Adjusts m_iocTemp
            }
            else
            {
                m_iocTemp = m_iocBase;
            }
        }
 public static bool FileExists(IOConnectionInfo ioc)
 {
     return(FileExists(ioc, false));
 }
Beispiel #22
0
 public FileTransactionEx(IOConnectionInfo iocBaseFile, bool bTransacted)
 {
     Initialize(iocBaseFile, bTransacted);
 }
        /// <summary>
        /// Rename/move a file. For local file system and WebDAV, the
        /// specified file is moved, i.e. the file destination can be
        /// in a different directory/path. In contrast, for FTP the
        /// file is renamed, i.e. its destination must be in the same
        /// directory/path.
        /// </summary>
        /// <param name="iocFrom">Source file path.</param>
        /// <param name="iocTo">Target file path.</param>
        public static void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo)
        {
            RaiseIOAccessPreEvent(iocFrom, iocTo, IOAccessType.Move);

#if NETSTANDARD2_0
            if (iocFrom.IsLocalFile())
            {
                m_FilesProvider.MoveFile(iocFrom.Path, iocTo.Path); return;
            }
#else
            if (iocFrom.IsLocalFile())
            {
                File.Move(iocFrom.Path, iocTo.Path); return;
            }
#endif

#if !KeePassLibSD && !NETSTANDARD2_0
            WebRequest req = CreateWebRequest(iocFrom);
            if (req != null)
            {
                string strToCnc = UrlUtil.GetCanonicalUri(iocTo.Path);

                if (IsHttpWebRequest(req))
                {
#if KeePassUAP
                    throw new NotSupportedException();
#else
                    req.Method = "MOVE";
                    req.Headers.Set("Destination", strToCnc);                     // Full URL supported
#endif
                }
                else if (IsFtpWebRequest(req))
                {
#if KeePassUAP
                    throw new NotSupportedException();
#else
                    req.Method = WebRequestMethods.Ftp.Rename;
                    string strToName = UrlUtil.GetFileName(strToCnc);

                    // We're affected by .NET bug 621450:
                    // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
                    // Prepending "./", "%2E/" or "Dummy/../" doesn't work.

                    ((FtpWebRequest)req).RenameTo = strToName;
#endif
                }
                else if (IsFileWebRequest(req))
                {
                    File.Move(UrlUtil.FileUrlToPath(iocFrom.Path),
                              UrlUtil.FileUrlToPath(iocTo.Path));
                    return;
                }
                else
                {
#if KeePassUAP
                    throw new NotSupportedException();
#else
                    req.Method = WrmMoveFile;
                    req.Headers.Set(WrhMoveFileTo, strToCnc);
#endif
                }

#if !KeePassUAP // Unreachable code
                DisposeResponse(req.GetResponse(), true);
#endif
            }
#endif

            // using(Stream sIn = IOConnection.OpenRead(iocFrom))
            // {
            //	using(Stream sOut = IOConnection.OpenWrite(iocTo))
            //	{
            //		MemUtil.CopyStream(sIn, sOut);
            //		sOut.Close();
            //	}
            //
            //	sIn.Close();
            // }
            // DeleteFile(iocFrom);
        }
Beispiel #24
0
        public void ChangeDatabase(string fileName, bool closeCurrent)
        {
            if (closeCurrent && host.MainWindow.DocumentManager.ActiveDatabase != null && host.MainWindow.DocumentManager.ActiveDatabase.IsOpen)
            {
                host.MainWindow.DocumentManager.CloseDatabase(host.MainWindow.DocumentManager.ActiveDatabase);
            }

            KeePassLib.Serialization.IOConnectionInfo ioci = null;

            if (fileName != null && fileName.Length > 0)
            {
                ioci = new KeePassLib.Serialization.IOConnectionInfo();
                ioci.Path = fileName;
            }

            host.MainWindow.BeginInvoke((MethodInvoker)delegate { promptUserToOpenDB(ioci); });
            return;
        }
 private static Stream OpenWriteLocal(IOConnectionInfo ioc)
 {
     return(m_FilesProvider.OpenWriteLocal(ioc.Path));
 }