~ubuntu-branches/ubuntu/wily/keepass2/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/fix-webdav-storage-with-mono-2.11.patch/KeePassLib/Serialization/IOConnection.cs

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2014-08-17 15:55:03 UTC
  • mfrom: (1.2.5)
  • Revision ID: package-import@ubuntu.com-20140817155503-3jcbkd107zug4clp
Tags: 2.27+dfsg-1
* New upstream release (Closes: #754575)
* remove upstream applied fix-webdav-storage-with-mono-2.11.patch
* add fix-autotype-paste.patch to fix pasting with autotype
* mention the need for the mono-mcs package to be installed for plugins to
  work in README.Debian (Closes: #749346)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
  KeePass Password Safe - The Open-Source Password Manager
3
 
  Copyright (C) 2003-2014 Dominik Reichl <dominik.reichl@t-online.de>
4
 
 
5
 
  This program is free software; you can redistribute it and/or modify
6
 
  it under the terms of the GNU General Public License as published by
7
 
  the Free Software Foundation; either version 2 of the License, or
8
 
  (at your option) any later version.
9
 
 
10
 
  This program is distributed in the hope that it will be useful,
11
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
  GNU General Public License for more details.
14
 
 
15
 
  You should have received a copy of the GNU General Public License
16
 
  along with this program; if not, write to the Free Software
17
 
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
*/
19
 
 
20
 
using System;
21
 
using System.Collections.Generic;
22
 
using System.Text;
23
 
using System.IO;
24
 
using System.Net;
25
 
using System.Diagnostics;
26
 
 
27
 
#if (!KeePassLibSD && !KeePassRT)
28
 
using System.Net.Cache;
29
 
using System.Net.Security;
30
 
#endif
31
 
 
32
 
#if !KeePassRT
33
 
using System.Security.Cryptography.X509Certificates;
34
 
#endif
35
 
 
36
 
using KeePassLib.Native;
37
 
using KeePassLib.Utility;
38
 
 
39
 
namespace KeePassLib.Serialization
40
 
{
41
 
#if (!KeePassLibSD && !KeePassRT)
42
 
        public sealed class IOWebClient : WebClient
43
 
        {
44
 
                protected override WebRequest GetWebRequest(Uri address)
45
 
                {
46
 
                        WebRequest request = base.GetWebRequest(address);
47
 
                        IOConnection.ConfigureWebRequest(request);
48
 
                        return request;
49
 
                }
50
 
        }
51
 
#endif
52
 
 
53
 
        public static class IOConnection
54
 
        {
55
 
#if (!KeePassLibSD && !KeePassRT)
56
 
                private static ProxyServerType m_pstProxyType = ProxyServerType.System;
57
 
                private static string m_strProxyAddr = string.Empty;
58
 
                private static string m_strProxyPort = string.Empty;
59
 
                private static string m_strProxyUserName = string.Empty;
60
 
                private static string m_strProxyPassword = string.Empty;
61
 
 
62
 
                private static bool m_bSslCertsAcceptInvalid = false;
63
 
                internal static bool SslCertsAcceptInvalid
64
 
                {
65
 
                        // get { return m_bSslCertsAcceptInvalid; }
66
 
                        set { m_bSslCertsAcceptInvalid = value; }
67
 
                }
68
 
#endif
69
 
 
70
 
                // Web request methods
71
 
                public const string WrmDeleteFile = "DELETEFILE";
72
 
                public const string WrmMoveFile = "MOVEFILE";
73
 
 
74
 
                // Web request headers
75
 
                public const string WrhMoveFileTo = "MoveFileTo";
76
 
 
77
 
                public static event EventHandler<IOAccessEventArgs> IOAccessPre;
78
 
 
79
 
#if (!KeePassLibSD && !KeePassRT)
80
 
                // Allow self-signed certificates, expired certificates, etc.
81
 
                private static bool AcceptCertificate(object sender,
82
 
                        X509Certificate certificate, X509Chain chain,
83
 
                        SslPolicyErrors sslPolicyErrors)
84
 
                {
85
 
                        return true;
86
 
                }
87
 
 
88
 
                internal static void SetProxy(ProxyServerType pst, string strAddr,
89
 
                        string strPort, string strUserName, string strPassword)
90
 
                {
91
 
                        m_pstProxyType = pst;
92
 
                        m_strProxyAddr = (strAddr ?? string.Empty);
93
 
                        m_strProxyPort = (strPort ?? string.Empty);
94
 
                        m_strProxyUserName = (strUserName ?? string.Empty);
95
 
                        m_strProxyPassword = (strPassword ?? string.Empty);
96
 
                }
97
 
 
98
 
                internal static void ConfigureWebRequest(WebRequest request)
99
 
                {
100
 
                        if(request == null) { Debug.Assert(false); return; } // No throw
101
 
 
102
 
                        // WebDAV support
103
 
                        if(request is HttpWebRequest)
104
 
                        {
105
 
                                request.PreAuthenticate = true; // Also auth GET
106
 
                                if(request.Method == WebRequestMethods.Http.Post)
107
 
                                        request.Method = WebRequestMethods.Http.Put;
108
 
                        }
109
 
                        // else if(request is FtpWebRequest)
110
 
                        // {
111
 
                        //      Debug.Assert(((FtpWebRequest)request).UsePassive);
112
 
                        // }
113
 
 
114
 
                        // Not implemented and ignored in Mono < 2.10
115
 
                        try
116
 
                        {
117
 
                                request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
118
 
                        }
119
 
                        catch(NotImplementedException) { }
120
 
                        catch(Exception) { Debug.Assert(false); }
121
 
 
122
 
                        try
123
 
                        {
124
 
                                IWebProxy prx;
125
 
                                if(GetWebProxy(out prx)) request.Proxy = prx;
126
 
                        }
127
 
                        catch(Exception) { Debug.Assert(false); }
128
 
                }
129
 
 
130
 
                internal static void ConfigureWebClient(WebClient wc)
131
 
                {
132
 
                        // Not implemented and ignored in Mono < 2.10
133
 
                        try
134
 
                        {
135
 
                                wc.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
136
 
                        }
137
 
                        catch(NotImplementedException) { }
138
 
                        catch(Exception) { Debug.Assert(false); }
139
 
 
140
 
                        try
141
 
                        {
142
 
                                IWebProxy prx;
143
 
                                if(GetWebProxy(out prx)) wc.Proxy = prx;
144
 
                        }
145
 
                        catch(Exception) { Debug.Assert(false); }
146
 
                }
147
 
 
148
 
                private static bool GetWebProxy(out IWebProxy prx)
149
 
                {
150
 
                        prx = null;
151
 
 
152
 
                        if(m_pstProxyType == ProxyServerType.None)
153
 
                                return true; // Use null proxy
154
 
                        if(m_pstProxyType == ProxyServerType.Manual)
155
 
                        {
156
 
                                try
157
 
                                {
158
 
                                        if(m_strProxyPort.Length > 0)
159
 
                                                prx = new WebProxy(m_strProxyAddr, int.Parse(m_strProxyPort));
160
 
                                        else prx = new WebProxy(m_strProxyAddr);
161
 
 
162
 
                                        if((m_strProxyUserName.Length > 0) || (m_strProxyPassword.Length > 0))
163
 
                                                prx.Credentials = new NetworkCredential(m_strProxyUserName,
164
 
                                                        m_strProxyPassword);
165
 
 
166
 
                                        return true; // Use manual proxy
167
 
                                }
168
 
                                catch(Exception exProxy)
169
 
                                {
170
 
                                        string strInfo = m_strProxyAddr;
171
 
                                        if(m_strProxyPort.Length > 0) strInfo += ":" + m_strProxyPort;
172
 
                                        MessageService.ShowWarning(strInfo, exProxy.Message);
173
 
                                }
174
 
 
175
 
                                return false; // Use default
176
 
                        }
177
 
 
178
 
                        if((m_strProxyUserName.Length == 0) && (m_strProxyPassword.Length == 0))
179
 
                                return false; // Use default proxy, no auth
180
 
 
181
 
                        try
182
 
                        {
183
 
                                prx = WebRequest.DefaultWebProxy;
184
 
                                if(prx == null) prx = WebRequest.GetSystemWebProxy();
185
 
                                if(prx == null) throw new InvalidOperationException();
186
 
 
187
 
                                prx.Credentials = new NetworkCredential(m_strProxyUserName,
188
 
                                        m_strProxyPassword);
189
 
                                return true;
190
 
                        }
191
 
                        catch(Exception) { Debug.Assert(false); }
192
 
 
193
 
                        return false;
194
 
                }
195
 
 
196
 
                private static void PrepareWebAccess()
197
 
                {
198
 
                        if(m_bSslCertsAcceptInvalid)
199
 
                                ServicePointManager.ServerCertificateValidationCallback =
200
 
                                        IOConnection.AcceptCertificate;
201
 
                        else
202
 
                                ServicePointManager.ServerCertificateValidationCallback = null;
203
 
                }
204
 
 
205
 
                private static IOWebClient CreateWebClient(IOConnectionInfo ioc)
206
 
                {
207
 
                        PrepareWebAccess();
208
 
 
209
 
                        IOWebClient wc = new IOWebClient();
210
 
                        ConfigureWebClient(wc);
211
 
 
212
 
                        if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
213
 
                                wc.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
214
 
                        else if(NativeLib.IsUnix()) // Mono requires credentials
215
 
                                wc.Credentials = new NetworkCredential("anonymous", string.Empty);
216
 
 
217
 
                        return wc;
218
 
                }
219
 
 
220
 
                private static WebRequest CreateWebRequest(IOConnectionInfo ioc)
221
 
                {
222
 
                        PrepareWebAccess();
223
 
 
224
 
                        WebRequest req = WebRequest.Create(ioc.Path);
225
 
                        ConfigureWebRequest(req);
226
 
 
227
 
                        if((ioc.UserName.Length > 0) || (ioc.Password.Length > 0))
228
 
                                req.Credentials = new NetworkCredential(ioc.UserName, ioc.Password);
229
 
                        else if(NativeLib.IsUnix()) // Mono requires credentials
230
 
                                req.Credentials = new NetworkCredential("anonymous", string.Empty);
231
 
 
232
 
                        return req;
233
 
                }
234
 
 
235
 
                public static Stream OpenRead(IOConnectionInfo ioc)
236
 
                {
237
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Read);
238
 
 
239
 
                        if(StrUtil.IsDataUri(ioc.Path))
240
 
                        {
241
 
                                byte[] pbData = StrUtil.DataUriToData(ioc.Path);
242
 
                                if(pbData != null) return new MemoryStream(pbData, false);
243
 
                        }
244
 
 
245
 
                        if(ioc.IsLocalFile()) return OpenReadLocal(ioc);
246
 
 
247
 
                        return CreateWebClient(ioc).OpenRead(new Uri(ioc.Path));
248
 
                }
249
 
#else
250
 
                public static Stream OpenRead(IOConnectionInfo ioc)
251
 
                {
252
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Read);
253
 
 
254
 
                        return OpenReadLocal(ioc);
255
 
                }
256
 
#endif
257
 
 
258
 
                private static Stream OpenReadLocal(IOConnectionInfo ioc)
259
 
                {
260
 
                        return new FileStream(ioc.Path, FileMode.Open, FileAccess.Read,
261
 
                                FileShare.Read);
262
 
                }
263
 
 
264
 
#if (!KeePassLibSD && !KeePassRT)
265
 
                public static Stream OpenWrite(IOConnectionInfo ioc)
266
 
                {
267
 
                        if(ioc == null) { Debug.Assert(false); return null; }
268
 
 
269
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Write);
270
 
 
271
 
                        if(ioc.IsLocalFile()) return OpenWriteLocal(ioc);
272
 
 
273
 
                        Uri uri = new Uri(ioc.Path);
274
 
 
275
 
                        // Mono does not set HttpWebRequest.Method to POST for writes,
276
 
                        // so one needs to set the method to PUT explicitly
277
 
                        if(NativeLib.IsUnix() && (uri.Scheme.Equals(Uri.UriSchemeHttp,
278
 
                                StrUtil.CaseIgnoreCmp) || uri.Scheme.Equals(Uri.UriSchemeHttps,
279
 
                                StrUtil.CaseIgnoreCmp)))
280
 
                                return CreateWebClient(ioc).OpenWrite(uri, WebRequestMethods.Http.Put);
281
 
 
282
 
                        return CreateWebClient(ioc).OpenWrite(uri);
283
 
                }
284
 
#else
285
 
                public static Stream OpenWrite(IOConnectionInfo ioc)
286
 
                {
287
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Write);
288
 
 
289
 
                        return OpenWriteLocal(ioc);
290
 
                }
291
 
#endif
292
 
 
293
 
                private static Stream OpenWriteLocal(IOConnectionInfo ioc)
294
 
                {
295
 
                        return new FileStream(ioc.Path, FileMode.Create, FileAccess.Write,
296
 
                                FileShare.None);
297
 
                }
298
 
 
299
 
                public static bool FileExists(IOConnectionInfo ioc)
300
 
                {
301
 
                        return FileExists(ioc, false);
302
 
                }
303
 
 
304
 
                public static bool FileExists(IOConnectionInfo ioc, bool bThrowErrors)
305
 
                {
306
 
                        if(ioc == null) { Debug.Assert(false); return false; }
307
 
 
308
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Exists);
309
 
 
310
 
                        if(ioc.IsLocalFile()) return File.Exists(ioc.Path);
311
 
 
312
 
#if (!KeePassLibSD && !KeePassRT)
313
 
                        if(ioc.Path.StartsWith("ftp://", StrUtil.CaseIgnoreCmp))
314
 
                        {
315
 
                                bool b = SendCommand(ioc, WebRequestMethods.Ftp.GetDateTimestamp);
316
 
                                if(!b && bThrowErrors) throw new InvalidOperationException();
317
 
                                return b;
318
 
                        }
319
 
#endif
320
 
 
321
 
                        try
322
 
                        {
323
 
                                Stream s = OpenRead(ioc);
324
 
                                if(s == null) throw new FileNotFoundException();
325
 
 
326
 
                                try { s.ReadByte(); }
327
 
                                catch(Exception) { }
328
 
 
329
 
                                // We didn't download the file completely; close may throw
330
 
                                // an exception -- that's okay
331
 
                                try { s.Close(); }
332
 
                                catch(Exception) { }
333
 
                        }
334
 
                        catch(Exception)
335
 
                        {
336
 
                                if(bThrowErrors) throw;
337
 
                                return false;
338
 
                        }
339
 
 
340
 
                        return true;
341
 
                }
342
 
 
343
 
                public static void DeleteFile(IOConnectionInfo ioc)
344
 
                {
345
 
                        RaiseIOAccessPreEvent(ioc, IOAccessType.Delete);
346
 
 
347
 
                        if(ioc.IsLocalFile()) { File.Delete(ioc.Path); return; }
348
 
 
349
 
#if (!KeePassLibSD && !KeePassRT)
350
 
                        WebRequest req = CreateWebRequest(ioc);
351
 
                        if(req != null)
352
 
                        {
353
 
                                if(req is HttpWebRequest) req.Method = "DELETE";
354
 
                                else if(req is FtpWebRequest) req.Method = WebRequestMethods.Ftp.DeleteFile;
355
 
                                else if(req is FileWebRequest)
356
 
                                {
357
 
                                        File.Delete(UrlUtil.FileUrlToPath(ioc.Path));
358
 
                                        return;
359
 
                                }
360
 
                                else req.Method = WrmDeleteFile;
361
 
 
362
 
                                DisposeResponse(req.GetResponse(), true);
363
 
                        }
364
 
#endif
365
 
                }
366
 
 
367
 
                /// <summary>
368
 
                /// Rename/move a file. For local file system and WebDAV, the
369
 
                /// specified file is moved, i.e. the file destination can be
370
 
                /// in a different directory/path. In contrast, for FTP the
371
 
                /// file is renamed, i.e. its destination must be in the same
372
 
                /// directory/path.
373
 
                /// </summary>
374
 
                /// <param name="iocFrom">Source file path.</param>
375
 
                /// <param name="iocTo">Target file path.</param>
376
 
                public static void RenameFile(IOConnectionInfo iocFrom, IOConnectionInfo iocTo)
377
 
                {
378
 
                        RaiseIOAccessPreEvent(iocFrom, iocTo, IOAccessType.Move);
379
 
 
380
 
                        if(iocFrom.IsLocalFile()) { File.Move(iocFrom.Path, iocTo.Path); return; }
381
 
 
382
 
#if (!KeePassLibSD && !KeePassRT)
383
 
                        WebRequest req = CreateWebRequest(iocFrom);
384
 
                        if(req != null)
385
 
                        {
386
 
                                if(req is HttpWebRequest)
387
 
                                {
388
 
                                        req.Method = "MOVE";
389
 
                                        req.Headers.Set("Destination", iocTo.Path); // Full URL supported
390
 
                                }
391
 
                                else if(req is FtpWebRequest)
392
 
                                {
393
 
                                        req.Method = WebRequestMethods.Ftp.Rename;
394
 
                                        string strTo = UrlUtil.GetFileName(iocTo.Path);
395
 
 
396
 
                                        // We're affected by .NET bug 621450:
397
 
                                        // https://connect.microsoft.com/VisualStudio/feedback/details/621450/problem-renaming-file-on-ftp-server-using-ftpwebrequest-in-net-framework-4-0-vs2010-only
398
 
                                        // Prepending "./", "%2E/" or "Dummy/../" doesn't work.
399
 
 
400
 
                                        ((FtpWebRequest)req).RenameTo = strTo;
401
 
                                }
402
 
                                else if(req is FileWebRequest)
403
 
                                {
404
 
                                        File.Move(UrlUtil.FileUrlToPath(iocFrom.Path),
405
 
                                                UrlUtil.FileUrlToPath(iocTo.Path));
406
 
                                        return;
407
 
                                }
408
 
                                else
409
 
                                {
410
 
                                        req.Method = WrmMoveFile;
411
 
                                        req.Headers.Set(WrhMoveFileTo, iocTo.Path);
412
 
                                }
413
 
 
414
 
                                DisposeResponse(req.GetResponse(), true);
415
 
                        }
416
 
#endif
417
 
 
418
 
                        // using(Stream sIn = IOConnection.OpenRead(iocFrom))
419
 
                        // {
420
 
                        //      using(Stream sOut = IOConnection.OpenWrite(iocTo))
421
 
                        //      {
422
 
                        //              MemUtil.CopyStream(sIn, sOut);
423
 
                        //              sOut.Close();
424
 
                        //      }
425
 
                        //
426
 
                        //      sIn.Close();
427
 
                        // }
428
 
                        // DeleteFile(iocFrom);
429
 
                }
430
 
 
431
 
#if (!KeePassLibSD && !KeePassRT)
432
 
                private static bool SendCommand(IOConnectionInfo ioc, string strMethod)
433
 
                {
434
 
                        try
435
 
                        {
436
 
                                WebRequest req = CreateWebRequest(ioc);
437
 
                                req.Method = strMethod;
438
 
                                DisposeResponse(req.GetResponse(), true);
439
 
                        }
440
 
                        catch(Exception) { return false; }
441
 
 
442
 
                        return true;
443
 
                }
444
 
#endif
445
 
 
446
 
                private static void DisposeResponse(WebResponse wr, bool bGetStream)
447
 
                {
448
 
                        if(wr == null) return;
449
 
 
450
 
                        try
451
 
                        {
452
 
                                if(bGetStream)
453
 
                                {
454
 
                                        Stream s = wr.GetResponseStream();
455
 
                                        if(s != null) s.Close();
456
 
                                }
457
 
                        }
458
 
                        catch(Exception) { Debug.Assert(false); }
459
 
 
460
 
                        try { wr.Close(); }
461
 
                        catch(Exception) { Debug.Assert(false); }
462
 
                }
463
 
 
464
 
                public static byte[] ReadFile(IOConnectionInfo ioc)
465
 
                {
466
 
                        Stream sIn = null;
467
 
                        MemoryStream ms = null;
468
 
                        try
469
 
                        {
470
 
                                sIn = IOConnection.OpenRead(ioc);
471
 
                                if(sIn == null) return null;
472
 
 
473
 
                                ms = new MemoryStream();
474
 
                                MemUtil.CopyStream(sIn, ms);
475
 
 
476
 
                                return ms.ToArray();
477
 
                        }
478
 
                        catch(Exception) { }
479
 
                        finally
480
 
                        {
481
 
                                if(sIn != null) sIn.Close();
482
 
                                if(ms != null) ms.Close();
483
 
                        }
484
 
 
485
 
                        return null;
486
 
                }
487
 
 
488
 
                private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc, IOAccessType t)
489
 
                {
490
 
                        RaiseIOAccessPreEvent(ioc, null, t);
491
 
                }
492
 
 
493
 
                private static void RaiseIOAccessPreEvent(IOConnectionInfo ioc,
494
 
                        IOConnectionInfo ioc2, IOAccessType t)
495
 
                {
496
 
                        if(ioc == null) { Debug.Assert(false); return; }
497
 
                        // ioc2 may be null
498
 
 
499
 
                        if(IOConnection.IOAccessPre != null)
500
 
                        {
501
 
                                IOConnectionInfo ioc2Lcl = ((ioc2 != null) ? ioc2.CloneDeep() : null);
502
 
                                IOAccessEventArgs e = new IOAccessEventArgs(ioc.CloneDeep(), ioc2Lcl, t);
503
 
                                IOConnection.IOAccessPre(null, e);
504
 
                        }
505
 
                }
506
 
        }
507
 
}