mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 23:50:18 -04:00
KeePassLib finally portable (but version 2.19)
Windows Store project stub
This commit is contained in:
468
ModernKeePassLib/Serialization/IOConnection.cs
Normal file
468
ModernKeePassLib/Serialization/IOConnection.cs
Normal file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
KeePass Password Safe - The Open-Source Password Manager
|
||||
Copyright (C) 2003-2012 Dominik Reichl <dominik.reichl@t-online.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
|
||||
using Windows.Storage.Streams;
|
||||
using Windows.Storage;
|
||||
// BERT TODO: For the time being, the web functionality is not available for WinRT
|
||||
|
||||
|
||||
#if !KeePassLibSD && TODO
|
||||
using System.Net.Cache;
|
||||
using System.Net.Security;
|
||||
#endif
|
||||
|
||||
using ModernKeePassLib.Utility;
|
||||
|
||||
namespace ModernKeePassLib.Serialization
|
||||
{
|
||||
#if !KeePassLibSD && false
|
||||
public sealed class IOWebClient : HttpClient
|
||||
{
|
||||
protected override WebRequest GetWebRequest(Uri address)
|
||||
{
|
||||
WebRequest request = base.GetWebRequest(address);
|
||||
IOConnection.ConfigureWebRequest(request);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public class IOConnection
|
||||
{
|
||||
#if !KeePassLibSD && TODO
|
||||
private static ProxyServerType m_pstProxyType = ProxyServerType.System;
|
||||
private static string m_strProxyAddr = string.Empty;
|
||||
private static string m_strProxyPort = string.Empty;
|
||||
private static string m_strProxyUserName = string.Empty;
|
||||
private static string m_strProxyPassword = string.Empty;
|
||||
#endif
|
||||
|
||||
// Web request methods
|
||||
public const string WrmDeleteFile = "DELETEFILE";
|
||||
public const string WrmMoveFile = "MOVEFILE";
|
||||
|
||||
// Web request headers
|
||||
public const string WrhMoveFileTo = "MoveFileTo";
|
||||
|
||||
#if !KeePassLibSD && TODO
|
||||
// Allow self-signed certificates, expired certificates, etc.
|
||||
private static bool ValidateServerCertificate(object sender,
|
||||
X509Certificate certificate, X509Chain chain,
|
||||
SslPolicyErrors sslPolicyErrors)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void SetProxy(ProxyServerType pst, string strAddr,
|
||||
string strPort, string strUserName, string strPassword)
|
||||
{
|
||||
m_pstProxyType = pst;
|
||||
m_strProxyAddr = (strAddr ?? string.Empty);
|
||||
m_strProxyPort = (strPort ?? string.Empty);
|
||||
m_strProxyUserName = (strUserName ?? string.Empty);
|
||||
m_strProxyPassword = (strPassword ?? string.Empty);
|
||||
}
|
||||
|
||||
internal static void ConfigureWebRequest(WebRequest request)
|
||||
{
|
||||
if(request == null) { Debug.Assert(false); return; } // No throw
|
||||
|
||||
// WebDAV support
|
||||
if(request is HttpWebRequest)
|
||||
{
|
||||
request.PreAuthenticate = true; // Also auth GET
|
||||
if(request.Method == WebRequestMethods.Http.Post)
|
||||
request.Method = WebRequestMethods.Http.Put;
|
||||
}
|
||||
// else if(request is FtpWebRequest)
|
||||
// {
|
||||
// Debug.Assert(((FtpWebRequest)request).UsePassive);
|
||||
// }
|
||||
|
||||
// Not implemented and ignored in Mono < 2.10
|
||||
try
|
||||
{
|
||||
request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
|
||||
}
|
||||
catch(NotImplementedException) { }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
try
|
||||
{
|
||||
IWebProxy prx;
|
||||
if(GetWebProxy(out prx)) request.Proxy = prx;
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
||||
internal static void ConfigureWebClient(WebClient wc)
|
||||
{
|
||||
// Not implemented and ignored in Mono < 2.10
|
||||
try
|
||||
{
|
||||
wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
|
||||
}
|
||||
catch(NotImplementedException) { }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
try
|
||||
{
|
||||
IWebProxy prx;
|
||||
if(GetWebProxy(out prx)) wc.Proxy = prx;
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
||||
private static bool GetWebProxy(out IWebProxy prx)
|
||||
{
|
||||
prx = null;
|
||||
|
||||
if(m_pstProxyType == ProxyServerType.None)
|
||||
return true; // Use null proxy
|
||||
if(m_pstProxyType == ProxyServerType.Manual)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_strProxyPort.Length > 0)
|
||||
prx = new WebProxy(m_strProxyAddr, int.Parse(m_strProxyPort));
|
||||
else prx = new WebProxy(m_strProxyAddr);
|
||||
|
||||
if((m_strProxyUserName.Length > 0) || (m_strProxyPassword.Length > 0))
|
||||
prx.Credentials = new NetworkCredential(m_strProxyUserName,
|
||||
m_strProxyPassword);
|
||||
|
||||
return true; // Use manual proxy
|
||||
}
|
||||
catch(Exception exProxy)
|
||||
{
|
||||
string strInfo = m_strProxyAddr;
|
||||
if(m_strProxyPort.Length > 0) strInfo += ":" + m_strProxyPort;
|
||||
MessageService.ShowWarning(strInfo, exProxy.Message);
|
||||
}
|
||||
|
||||
return false; // Use default
|
||||
}
|
||||
|
||||
if((m_strProxyUserName.Length == 0) && (m_strProxyPassword.Length == 0))
|
||||
return false; // Use default proxy, no auth
|
||||
|
||||
try
|
||||
{
|
||||
prx = WebRequest.DefaultWebProxy;
|
||||
if(prx == null) prx = WebRequest.GetSystemWebProxy();
|
||||
if(prx == null) throw new InvalidOperationException();
|
||||
|
||||
prx.Credentials = new NetworkCredential(m_strProxyUserName,
|
||||
m_strProxyPassword);
|
||||
return true;
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void PrepareWebAccess()
|
||||
{
|
||||
ServicePointManager.ServerCertificateValidationCallback =
|
||||
ValidateServerCertificate;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static WebRequest CreateWebRequest(IOConnectionInfo ioc)
|
||||
{
|
||||
PrepareWebAccess();
|
||||
|
||||
WebRequest req = WebRequest.Create(ioc.Path);
|
||||
ConfigureWebRequest(req);
|
||||
|
||||
if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
|
||||
req.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
|
||||
else if(NativeLib.IsUnix()) // Mono requires credentials
|
||||
req.Credentials = new NetworkCredential("anonymous", string.Empty);
|
||||
|
||||
return req;
|
||||
}
|
||||
#endif
|
||||
|
||||
private async Task<Stream> OpenReadHttp(IOConnectionInfo ioc)
|
||||
{
|
||||
|
||||
// TODO: Configure the httpClient
|
||||
// PrepareWebAccess();
|
||||
// ConfigureWebClient(wc);
|
||||
|
||||
HttpClient hc = new HttpClient();
|
||||
HttpResponseMessage response = await hc.GetAsync(ioc.Path);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
// Read content into buffer
|
||||
// Not the most efficient thing to do,
|
||||
// but simplifies our life by allowing to use stream.length later on.
|
||||
await response.Content.LoadIntoBufferAsync();
|
||||
return await response.Content.ReadAsStreamAsync();
|
||||
#if false
|
||||
if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
|
||||
wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
|
||||
else if(NativeLib.IsUnix()) // Mono requires credentials
|
||||
wc.Credentials = new NetworkCredential("anonymous", string.Empty);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
public async Task<Stream> OpenRead(IOConnectionInfo ioc)
|
||||
{
|
||||
if(StrUtil.IsDataUri(ioc.Path))
|
||||
{
|
||||
byte[] pbData = StrUtil.DataUriToData(ioc.Path);
|
||||
if(pbData != null) return new MemoryStream(pbData, false);
|
||||
}
|
||||
|
||||
if(ioc.IsLocalFile()) return await OpenReadLocal(ioc);
|
||||
|
||||
|
||||
return await OpenReadHttp(ioc);
|
||||
}
|
||||
|
||||
|
||||
private async Task<Stream> OpenReadLocal(IOConnectionInfo ioc)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sampleFile = await StorageFile.GetFileFromPathAsync(ioc.Path);
|
||||
using (IRandomAccessStream stream = await sampleFile.OpenAsync(FileAccessMode.Read))
|
||||
{
|
||||
return stream.AsStream();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.Assert(false, "Not implemented yet");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#if !KeePassLibSD && TODO
|
||||
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||
{
|
||||
if(ioc == null) { Debug.Assert(false); return null; }
|
||||
|
||||
if(ioc.IsLocalFile()) return OpenWriteLocal(ioc);
|
||||
|
||||
Uri uri = new Uri(ioc.Path);
|
||||
|
||||
// Mono does not set HttpWebRequest.Method to POST for writes,
|
||||
// so one needs to set the method to PUT explicitly
|
||||
if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
|
||||
StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
|
||||
StrUtil.CaseIgnoreCmp)))
|
||||
return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
|
||||
|
||||
return CreateWebClient(ioc).OpenWrite(uri);
|
||||
}
|
||||
#else
|
||||
public static Stream OpenWrite(IOConnectionInfo ioc)
|
||||
{
|
||||
return OpenWriteLocal(ioc);
|
||||
}
|
||||
#endif
|
||||
|
||||
private static Stream OpenWriteLocal(IOConnectionInfo ioc)
|
||||
{
|
||||
Debug.Assert(false, "Not implemented yet");
|
||||
return null;
|
||||
// return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write,
|
||||
// FileShare.None);
|
||||
}
|
||||
|
||||
public static bool FileExists(IOConnectionInfo ioc)
|
||||
{
|
||||
return FileExists(ioc, false);
|
||||
}
|
||||
|
||||
public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors)
|
||||
{
|
||||
Debug.Assert(false, "Not implemented yet");
|
||||
return false;
|
||||
#if TODO
|
||||
|
||||
if(ioc == null) { Debug.Assert(false); return false; }
|
||||
|
||||
if(ioc.IsLocalFile()) return File.Exists(ioc.Path);
|
||||
|
||||
try
|
||||
{
|
||||
Stream s = OpenRead(ioc);
|
||||
if(s == null) throw new FileNotFoundException();
|
||||
|
||||
// For FTP clients we called RETR to get the file, but we never
|
||||
// followed-up and downloaded the file; close may produce a
|
||||
// 550 error -- that's okay
|
||||
try { s.Close(); }
|
||||
catch(Exception) { }
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
if(bThrowErrors) throw;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void DeleteFile(IOConnectionInfo ioc)
|
||||
{
|
||||
Debug.Assert(false, "Not implemented yet");
|
||||
return ;
|
||||
#if TODO
|
||||
if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
|
||||
|
||||
#if !KeePassLibSD && TODO
|
||||
WebRequest req = CreateWebRequest(ioc);
|
||||
if(req != null)
|
||||
{
|
||||
if(req is HttpWebRequest) req.Method = "DELETE";
|
||||
else if(req is FtpWebRequest) req.Method = WebRequestMethods.Ftp.DeleteFile;
|
||||
else if(req is FileWebRequest)
|
||||
{
|
||||
File.Delete(UrlUtil.FileUrlToPath(ioc.Path));
|
||||
return;
|
||||
}
|
||||
else req.Method = WrmDeleteFile;
|
||||
|
||||
DisposeResponse(req.GetResponse(), true);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <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)
|
||||
{
|
||||
return;
|
||||
#if TODO
|
||||
if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; }
|
||||
|
||||
#if !KeePassLibSD && TODO
|
||||
WebRequest req = CreateWebRequest(iocFrom);
|
||||
if(req != null)
|
||||
{
|
||||
if(req is HttpWebRequest)
|
||||
{
|
||||
req.Method = "MOVE";
|
||||
req.Headers.Set("Destination", iocTo.Path); // Full URL supported
|
||||
}
|
||||
else if(req is FtpWebRequest)
|
||||
{
|
||||
req.Method = WebRequestMethods.Ftp.Rename;
|
||||
((FtpWebRequest)req).RenameTo = UrlUtil.GetFileName(iocTo.Path);
|
||||
}
|
||||
else if(req is FileWebRequest)
|
||||
{
|
||||
File.Move(UrlUtil.FileUrlToPath(iocFrom.Path),
|
||||
UrlUtil.FileUrlToPath(iocTo.Path));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
req.Method = WrmMoveFile;
|
||||
req.Headers.Set(WrhMoveFileTo, iocTo.Path);
|
||||
}
|
||||
|
||||
DisposeResponse(req.GetResponse(), true);
|
||||
}
|
||||
#endif
|
||||
|
||||
// using(Stream sIn = IOConnection.OpenRead(iocFrom))
|
||||
// {
|
||||
// using(Stream sOut = IOConnection.OpenWrite(iocTo))
|
||||
// {
|
||||
// MemUtil.CopyStream(sIn, sOut);
|
||||
// sOut.Close();
|
||||
// }
|
||||
//
|
||||
// sIn.Close();
|
||||
// }
|
||||
// DeleteFile(iocFrom);
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void DisposeResponse(WebResponse wr, bool bGetStream)
|
||||
{
|
||||
Debug.Assert(false, "Not implemented yet");
|
||||
return;
|
||||
#if TODO
|
||||
if(wr == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
if(bGetStream)
|
||||
{
|
||||
Stream s = wr.GetResponseStream();
|
||||
if(s != null) s.Close();
|
||||
}
|
||||
}
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
|
||||
try { wr.Close(); }
|
||||
catch(Exception) { Debug.Assert(false); }
|
||||
}
|
||||
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user