Martin Prikryl 11 年之前
父节点
当前提交
0c93cf6567
共有 86 个文件被更改,包括 623 次插入656 次删除
  1. 18 17
      dotnet/Session.cs
  2. 15 0
      dotnet/SessionOptions.cs
  3. 4 4
      dotnet/internal/SessionLogReader.cs
  4. 3 3
      dotnet/properties/AssemblyInfo.cs
  5. 7 2
      libs/openssl/ACKNOWLEDGMENTS
  6. 1 1
      libs/openssl/crypto/asn1/a_strnid.c
  7. 26 20
      libs/openssl/crypto/bn/bn_mont.c
  8. 2 2
      libs/openssl/crypto/buildinf.h
  9. 1 1
      libs/openssl/crypto/dso/dso_dlfcn.c
  10. 1 0
      libs/openssl/crypto/evp/bio_b64.c
  11. 1 0
      libs/openssl/crypto/evp/encode.c
  12. 3 3
      libs/openssl/crypto/opensslv.h
  13. 8 0
      libs/openssl/crypto/pkcs12/p12_crt.c
  14. 1 1
      libs/openssl/crypto/pkcs12/p12_kiss.c
  15. 6 0
      libs/openssl/crypto/pkcs7/pk7_doit.c
  16. 1 0
      libs/openssl/crypto/pkcs7/pkcs7.h
  17. 2 1
      libs/openssl/crypto/pkcs7/pkcs7err.c
  18. 1 1
      libs/openssl/crypto/rsa/rsa_ameth.c
  19. 3 0
      libs/openssl/crypto/srp/srp_vfy.c
  20. 1 0
      libs/openssl/crypto/ts/ts_rsp_verify.c
  21. 3 3
      libs/openssl/crypto/x509v3/v3_purp.c
  22. 12 3
      libs/openssl/ssl/d1_both.c
  23. 6 3
      libs/openssl/ssl/d1_lib.c
  24. 10 9
      libs/openssl/ssl/d1_pkt.c
  25. 1 0
      libs/openssl/ssl/d1_srvr.c
  26. 9 0
      libs/openssl/ssl/s3_clnt.c
  27. 35 7
      libs/openssl/ssl/s3_pkt.c
  28. 17 16
      libs/openssl/ssl/s3_srvr.c
  29. 3 1
      libs/openssl/ssl/ssl.h
  30. 1 0
      libs/openssl/ssl/ssl3.h
  31. 4 0
      libs/openssl/ssl/ssl_asn1.c
  32. 1 1
      libs/openssl/ssl/ssl_err.c
  33. 4 0
      libs/openssl/ssl/ssl_lib.c
  34. 2 6
      libs/openssl/ssl/t1_enc.c
  35. 24 21
      libs/openssl/ssl/t1_lib.c
  36. 0 179
      libs/zlib/zlib.vcxproj
  37. 2 2
      readme_mfc.txt
  38. 1 1
      source/Console.cbproj
  39. 1 1
      source/DragExt.cbproj
  40. 2 2
      source/DragExt64.rc
  41. 2 2
      source/WinSCP.cbproj
  42. 13 1
      source/components/UnixDirView.cpp
  43. 6 1
      source/core/Common.cpp
  44. 1 0
      source/core/Common.h
  45. 8 0
      source/core/CoreMain.cpp
  46. 2 1
      source/core/FtpFileSystem.cpp
  47. 1 0
      source/core/Interface.h
  48. 7 4
      source/core/Queue.cpp
  49. 3 2
      source/core/RemoteFiles.cpp
  50. 3 1
      source/core/SecureShell.cpp
  51. 7 3
      source/core/SessionInfo.cpp
  52. 33 27
      source/core/Terminal.cpp
  53. 6 4
      source/core/Terminal.h
  54. 1 1
      source/core/Usage.h
  55. 1 0
      source/core/WebDAVFileSystem.cpp
  56. 0 5
      source/dragext/DragExt.cpp
  57. 0 235
      source/filezilla/AsyncSslSocketLayer.cpp
  58. 0 13
      source/filezilla/AsyncSslSocketLayer.h
  59. 0 1
      source/filezilla/FileZillaApi.cpp
  60. 18 1
      source/filezilla/FtpListResult.cpp
  61. 1 4
      source/forms/Authenticate.cpp
  62. 13 5
      source/forms/CustomScpExplorer.cpp
  63. 1 1
      source/forms/FileFind.cpp
  64. 16 1
      source/forms/Login.cpp
  65. 2 2
      source/forms/MessageDlg.cpp
  66. 1 1
      source/forms/Progress.cpp
  67. 1 1
      source/forms/ScpCommander.cpp
  68. 2 2
      source/forms/Synchronize.cpp
  69. 1 1
      source/forms/SynchronizeProgress.cpp
  70. 11 2
      source/packages/filemng/DirView.pas
  71. 12 0
      source/packages/filemng/DriveView.pas
  72. 26 0
      source/packages/my/NortonLikeListView.pas
  73. 12 0
      source/packages/my/PasTools.pas
  74. 8 3
      source/packages/my/TcpIp.pas
  75. 1 1
      source/packages/tb2k/LICENSE.txt
  76. 1 0
      source/resource/HelpWin.h
  77. 7 1
      source/resource/TextsCore1.rc
  78. 1 1
      source/resource/TextsWin1.rc
  79. 56 14
      source/windows/GUITools.cpp
  80. 1 0
      source/windows/GUITools.h
  81. 5 0
      source/windows/Setup.cpp
  82. 16 1
      source/windows/TerminalManager.cpp
  83. 1 0
      source/windows/TerminalManager.h
  84. 24 2
      source/windows/Tools.cpp
  85. 46 0
      source/windows/WinInterface.cpp
  86. 2 0
      source/windows/WinInterface.h

+ 18 - 17
dotnet/Session.cs

@@ -470,32 +470,33 @@ namespace WinSCP
                         throw new ArgumentOutOfRangeException("mode");
                 }
 
-                List<string> criteriaNames = new List<string>();
-                if ((criteria & SynchronizationCriteria.Time) == SynchronizationCriteria.Time)
+                string criteriaName;
+                switch (criteria)
                 {
-                    criteria -= SynchronizationCriteria.Time;
-                    criteriaNames.Add("time");
-                }
-
-                if ((criteria & SynchronizationCriteria.Size) == SynchronizationCriteria.Size)
-                {
-                    criteria -= SynchronizationCriteria.Size;
-                    criteriaNames.Add("size");
-                }
-
-                if (criteria != 0)
-                {
-                    throw new ArgumentOutOfRangeException("criteria");
+                    case SynchronizationCriteria.None:
+                        criteriaName = "none";
+                        break;
+                    case SynchronizationCriteria.Time:
+                        criteriaName = "time";
+                        break;
+                    case SynchronizationCriteria.Size:
+                        criteriaName = "size";
+                        break;
+                    case SynchronizationCriteria.Either:
+                        criteriaName = "either";
+                        break;
+                    default:
+                        throw new ArgumentOutOfRangeException("criteria");
                 }
 
                 WriteCommand(
                     string.Format(CultureInfo.InvariantCulture,
-                        "synchronize {0} {1} {2} {3} {4} -- \"{5}\" \"{6}\"",
+                        "synchronize {0} {1} {2} {3} -criteria=\"{4}\" -- \"{5}\" \"{6}\"",
                         modeName,
                         BooleanSwitch(removeFiles, "delete"),
                         BooleanSwitch(mirror, "mirror"),
                         options.ToSwitches(),
-                        FormatSwitch("criteria", string.Join(",", criteriaNames.ToArray())),
+                        criteriaName,
                         ArgumentEscape(localPath), ArgumentEscape(remotePath)));
 
                 return ReadSynchronizeDirectories();

+ 15 - 0
dotnet/SessionOptions.cs

@@ -50,6 +50,7 @@ namespace WinSCP
         public string UserName { get; set; }
         public string Password { get; set; }
         public TimeSpan Timeout { get { return _timeout; } set { SetTimeout(value); } }
+        public int TimeoutInMilliseconds { get { return GetTimeoutInMilliseconds(); } set { SetTimeoutInMilliseconds(value); } }
 
         // SSH
         public string SshHostKeyFingerprint { get { return _sshHostKeyFingerprint; } set { SetSshHostKeyFingerprint(value); } }
@@ -124,6 +125,20 @@ namespace WinSCP
             _portNumber = value;
         }
 
+        private int GetTimeoutInMilliseconds()
+        {
+            if ((Timeout.TotalMilliseconds > int.MaxValue) || (Timeout.TotalMilliseconds < int.MinValue))
+            {
+                throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Cannot convert {0} to integer", Timeout));
+            }
+            return (int)Timeout.TotalMilliseconds;
+        }
+
+        private void SetTimeoutInMilliseconds(int value)
+        {
+            Timeout = TimeSpan.FromMilliseconds(value);
+        }
+
         private string _sshHostKeyFingerprint;
         private string _tlsHostCertificateFingerprint;
         private TimeSpan _timeout;

+ 4 - 4
dotnet/internal/SessionLogReader.cs

@@ -188,8 +188,6 @@ namespace WinSCP
 
         private void OpenLog()
         {
-            Session.Logger.WriteLine("Opening log");
-
             if (_closed)
             {
                 throw new InvalidOperationException("Log was closed already");
@@ -197,22 +195,24 @@ namespace WinSCP
 
             try
             {
+                Session.Logger.WriteLine("Opening log without write sharing");
                 // First try to open file without write sharing.
                 // This fails, if WinSCP is still writing to the log file.
                 // This is done only as a way to detect that log file is not complete yet.
                 _stream = File.Open(Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                 _closed = true;
-                Session.Logger.WriteLine("Log opened without write sharing");
                 LogContents();
             }
             catch (IOException)
             {
+                Session.Logger.WriteLine("Opening log with write sharing");
                 // If log file is still being written to, open it with write sharing
                 _stream = OpenLogFileWithWriteSharing();
                 _closed = false;
-                Session.Logger.WriteLine("Log opened with write sharing");
             }
 
+            Session.Logger.WriteLine("Log opened");
+
             _reader = XmlReader.Create(_stream);
 
             int skip = _position;

+ 3 - 3
dotnet/properties/AssemblyInfo.cs

@@ -19,9 +19,9 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.1.5.0")]
-[assembly: AssemblyFileVersion("1.1.5.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.5.3.0")]
+[assembly: AssemblyVersion("1.1.6.0")]
+[assembly: AssemblyFileVersion("1.1.6.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.5.4.0")]
 
 [assembly: CLSCompliant(true)]
 

+ 7 - 2
libs/openssl/ACKNOWLEDGMENTS

@@ -10,13 +10,18 @@ OpenSSL project.
 We would like to identify and thank the following such sponsors for their past
 or current significant support of the OpenSSL project:
 
+Major support:
+
+	Qualys		http://www.qualys.com/
+
 Very significant support:
 
-	OpenGear: www.opengear.com
+	OpenGear:	http://www.opengear.com/
 
 Significant support:
 
-	PSW Group: www.psw.net
+	PSW Group:	http://www.psw.net/
+	Acano Ltd.	http://acano.com/
 
 Please note that we ask permission to identify sponsors and that some sponsors
 we consider eligible for inclusion here have requested to remain anonymous.

+ 1 - 1
libs/openssl/crypto/asn1/a_strnid.c

@@ -74,7 +74,7 @@ static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
  * certain software (e.g. Netscape) has problems with them.
  */
 
-static unsigned long global_mask = 0xFFFFFFFFL;
+static unsigned long global_mask = B_ASN1_UTF8STRING;
 
 void ASN1_STRING_set_default_mask(unsigned long mask)
 {

+ 26 - 20
libs/openssl/crypto/bn/bn_mont.c

@@ -478,32 +478,38 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
 BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
 					const BIGNUM *mod, BN_CTX *ctx)
 	{
-	int got_write_lock = 0;
 	BN_MONT_CTX *ret;
 
 	CRYPTO_r_lock(lock);
-	if (!*pmont)
+	ret = *pmont;
+	CRYPTO_r_unlock(lock);
+	if (ret)
+		return ret;
+
+	/* We don't want to serialise globally while doing our lazy-init math in
+	 * BN_MONT_CTX_set. That punishes threads that are doing independent
+	 * things. Instead, punish the case where more than one thread tries to
+	 * lazy-init the same 'pmont', by having each do the lazy-init math work
+	 * independently and only use the one from the thread that wins the race
+	 * (the losers throw away the work they've done). */
+	ret = BN_MONT_CTX_new();
+	if (!ret)
+		return NULL;
+	if (!BN_MONT_CTX_set(ret, mod, ctx))
 		{
-		CRYPTO_r_unlock(lock);
-		CRYPTO_w_lock(lock);
-		got_write_lock = 1;
+		BN_MONT_CTX_free(ret);
+		return NULL;
+		}
 
-		if (!*pmont)
-			{
-			ret = BN_MONT_CTX_new();
-			if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
-				BN_MONT_CTX_free(ret);
-			else
-				*pmont = ret;
-			}
+	/* The locked compare-and-set, after the local work is done. */
+	CRYPTO_w_lock(lock);
+	if (*pmont)
+		{
+		BN_MONT_CTX_free(ret);
+		ret = *pmont;
 		}
-	
-	ret = *pmont;
-	
-	if (got_write_lock)
-		CRYPTO_w_unlock(lock);
 	else
-		CRYPTO_r_unlock(lock);
-		
+		*pmont = ret;
+	CRYPTO_w_unlock(lock);
 	return ret;
 	}

+ 2 - 2
libs/openssl/crypto/buildinf.h

@@ -9,11 +9,11 @@
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "cl  /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS  -DDSO_WIN32  -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE    "
   #define PLATFORM "VC-WIN32"
-  #define DATE "Wed Apr  9 09:25:41 2014"
+  #define DATE "Tue Jun 10 08:36:59 2014"
 #endif
 #ifdef MK1MF_PLATFORM_BC_NT
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -D_timeb=timeb -D_ftime=ftime -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_DYNAMIC_ENGINE    "
   #define PLATFORM "BC-NT"
-  #define DATE "Wed Apr  9 09:25:42 2014"
+  #define DATE "Tue Jun 10 08:37:00 2014"
 #endif

+ 1 - 1
libs/openssl/crypto/dso/dso_dlfcn.c

@@ -464,7 +464,7 @@ static int dlfcn_pathbyaddr(void *addr,char *path,int sz)
 		return len;
 		}
 
-	ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
+	ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror());
 #endif
 	return -1;
 	}

+ 1 - 0
libs/openssl/crypto/evp/bio_b64.c

@@ -226,6 +226,7 @@ static int b64_read(BIO *b, char *out, int outl)
 		else if (ctx->start)
 			{
 			q=p=(unsigned char *)ctx->tmp;
+			num = 0;
 			for (j=0; j<i; j++)
 				{
 				if (*(q++) != '\n') continue;

+ 1 - 0
libs/openssl/crypto/evp/encode.c

@@ -324,6 +324,7 @@ int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
 				v=EVP_DecodeBlock(out,d,n);
 				n=0;
 				if (v < 0) { rv=0; goto end; }
+				if (eof > v) { rv=-1; goto end; }
 				ret+=(v-eof);
 				}
 			else

+ 3 - 3
libs/openssl/crypto/opensslv.h

@@ -25,11 +25,11 @@
  * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
  *  major minor fix final patch/beta)
  */
-#define OPENSSL_VERSION_NUMBER	0x1000107fL
+#define OPENSSL_VERSION_NUMBER	0x1000108fL
 #ifdef OPENSSL_FIPS
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1g-fips 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1h-fips 5 Jun 2014"
 #else
-#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1g 7 Apr 2014"
+#define OPENSSL_VERSION_TEXT	"OpenSSL 1.0.1h 5 Jun 2014"
 #endif
 #define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
 

+ 8 - 0
libs/openssl/crypto/pkcs12/p12_crt.c

@@ -96,7 +96,11 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
 			nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
 		else
 #endif
+#ifdef OPENSSL_NO_RC2
+		nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
 		nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
 		}
 	if (!nid_key)
 		nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
@@ -286,7 +290,11 @@ int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
 		free_safes = 0;
 
 	if (nid_safe == 0)
+#ifdef OPENSSL_NO_RC2
+		nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+#else
 		nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
+#endif
 
 	if (nid_safe == -1)
 		p7 = PKCS12_pack_p7data(bags);

+ 1 - 1
libs/openssl/crypto/pkcs12/p12_kiss.c

@@ -269,7 +269,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
 			int len, r;
 			unsigned char *data;
 			len = ASN1_STRING_to_UTF8(&data, fname);
-			if(len > 0) {
+			if(len >= 0) {
 				r = X509_alias_set1(x509, data, len);
 				OPENSSL_free(data);
 				if (!r)

+ 6 - 0
libs/openssl/crypto/pkcs7/pk7_doit.c

@@ -440,6 +440,11 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
 		{
 	case NID_pkcs7_signed:
 		data_body=PKCS7_get_octet_string(p7->d.sign->contents);
+		if (!PKCS7_is_detached(p7) && data_body == NULL)
+			{
+			PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_INVALID_SIGNED_DATA_TYPE);
+			goto err;
+			}
 		md_sk=p7->d.sign->md_algs;
 		break;
 	case NID_pkcs7_signedAndEnveloped:
@@ -928,6 +933,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
 	if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
 		goto err;
 	OPENSSL_free(abuf);
+	abuf = NULL;
 	if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
 		goto err;
 	abuf = OPENSSL_malloc(siglen);

+ 1 - 0
libs/openssl/crypto/pkcs7/pkcs7.h

@@ -453,6 +453,7 @@ void ERR_load_PKCS7_strings(void);
 #define PKCS7_R_ERROR_SETTING_CIPHER			 121
 #define PKCS7_R_INVALID_MIME_TYPE			 131
 #define PKCS7_R_INVALID_NULL_POINTER			 143
+#define PKCS7_R_INVALID_SIGNED_DATA_TYPE		 155
 #define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
 #define PKCS7_R_MIME_PARSE_ERROR			 133
 #define PKCS7_R_MIME_SIG_PARSE_ERROR			 134

+ 2 - 1
libs/openssl/crypto/pkcs7/pkcs7err.c

@@ -1,6 +1,6 @@
 /* crypto/pkcs7/pkcs7err.c */
 /* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2014 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -130,6 +130,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
 {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
 {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE)   ,"invalid mime type"},
 {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER),"invalid null pointer"},
+{ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE),"invalid signed data type"},
 {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE),"mime no content type"},
 {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR)    ,"mime parse error"},
 {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR),"mime sig parse error"},

+ 1 - 1
libs/openssl/crypto/rsa/rsa_ameth.c

@@ -358,7 +358,7 @@ static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss,
 		if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0)
 			goto err;
 		}
-	else if (BIO_puts(bp, "0x14 (default)") <= 0)
+	else if (BIO_puts(bp, "14 (default)") <= 0)
 		goto err;
 	BIO_puts(bp, "\n");
 

+ 3 - 0
libs/openssl/crypto/srp/srp_vfy.c

@@ -93,6 +93,9 @@ static int t_fromb64(unsigned char *a, const char *src)
 		else a[i] = loc - b64table;
 		++i;
 		}
+	/* if nothing valid to process we have a zero length response */
+	if (i == 0)
+		return 0;
 	size = i;
 	i = size - 1;
 	j = size;

+ 1 - 0
libs/openssl/crypto/ts/ts_rsp_verify.c

@@ -629,6 +629,7 @@ static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info,
 	X509_ALGOR_free(*md_alg);
 	OPENSSL_free(*imprint);
 	*imprint_len = 0;
+	*imprint = NULL;
 	return 0;
 	}
 

+ 3 - 3
libs/openssl/crypto/x509v3/v3_purp.c

@@ -389,8 +389,8 @@ static void x509v3_cache_extensions(X509 *x)
 	/* Handle proxy certificates */
 	if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
 		if (x->ex_flags & EXFLAG_CA
-		    || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
-		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
+		    || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
+		    || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
 			x->ex_flags |= EXFLAG_INVALID;
 		}
 		if (pci->pcPathLengthConstraint) {
@@ -670,7 +670,7 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
 		return 0;
 
 	/* Extended Key Usage MUST be critical */
-	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, 0);
+	i_ext = X509_get_ext_by_NID((X509 *) x, NID_ext_key_usage, -1);
 	if (i_ext >= 0)
 		{
 		X509_EXTENSION *ext = X509_get_ext((X509 *) x, i_ext);

+ 12 - 3
libs/openssl/ssl/d1_both.c

@@ -627,7 +627,16 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
 		frag->msg_header.frag_off = 0;
 		}
 	else
+		{
 		frag = (hm_fragment*) item->data;
+		if (frag->msg_header.msg_len != msg_hdr->msg_len)
+			{
+			item = NULL;
+			frag = NULL;
+			goto err;
+			}
+		}
+
 
 	/* If message is already reassembled, this must be a
 	 * retransmit and can be dropped.
@@ -674,8 +683,8 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
 		item = pitem_new(seq64be, frag);
 		if (item == NULL)
 			{
-			goto err;
 			i = -1;
+			goto err;
 			}
 
 		pqueue_insert(s->d1->buffered_messages, item);
@@ -784,6 +793,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
 	int i,al;
 	struct hm_header_st msg_hdr;
 
+	redo:
 	/* see if we have the required fragment already */
 	if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
 		{
@@ -842,8 +852,7 @@ dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
 					s->msg_callback_arg);
 			
 			s->init_num = 0;
-			return dtls1_get_message_fragment(s, st1, stn,
-				max, ok);
+			goto redo;
 			}
 		else /* Incorrectly formated Hello request */
 			{

+ 6 - 3
libs/openssl/ssl/d1_lib.c

@@ -176,9 +176,12 @@ static void dtls1_clear_queues(SSL *s)
 
 	while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL)
 		{
-		frag = (hm_fragment *)item->data;
-		OPENSSL_free(frag->fragment);
-		OPENSSL_free(frag);
+		rdata = (DTLS1_RECORD_DATA *) item->data;
+		if (rdata->rbuf.buf)
+			{
+			OPENSSL_free(rdata->rbuf.buf);
+			}
+		OPENSSL_free(item->data);
 		pitem_free(item);
 		}
 	}

+ 10 - 9
libs/openssl/ssl/d1_pkt.c

@@ -239,14 +239,6 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 	}
 #endif
 
-	/* insert should not fail, since duplicates are dropped */
-	if (pqueue_insert(queue->q, item) == NULL)
-		{
-		OPENSSL_free(rdata);
-		pitem_free(item);
-		return(0);
-		}
-
 	s->packet = NULL;
 	s->packet_length = 0;
 	memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER));
@@ -259,7 +251,16 @@ dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
 		pitem_free(item);
 		return(0);
 		}
-	
+
+	/* insert should not fail, since duplicates are dropped */
+	if (pqueue_insert(queue->q, item) == NULL)
+		{
+		SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+		OPENSSL_free(rdata);
+		pitem_free(item);
+		return(0);
+		}
+
 	return(1);
 	}
 

+ 1 - 0
libs/openssl/ssl/d1_srvr.c

@@ -1356,6 +1356,7 @@ int dtls1_send_server_key_exchange(SSL *s)
 			    (unsigned char *)encodedPoint, 
 			    encodedlen);
 			OPENSSL_free(encodedPoint);
+			encodedPoint = NULL;
 			p += encodedlen;
 			}
 #endif

+ 9 - 0
libs/openssl/ssl/s3_clnt.c

@@ -559,6 +559,7 @@ int ssl3_connect(SSL *s)
 		case SSL3_ST_CR_FINISHED_A:
 		case SSL3_ST_CR_FINISHED_B:
 
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
 				SSL3_ST_CR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -915,6 +916,7 @@ int ssl3_get_server_hello(SSL *s)
 		SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
 		goto f_err;
 		}
+	    s->s3->flags |= SSL3_FLAGS_CCS_OK;
 	    s->hit=1;
 	    }
 	else	/* a miss or crap from the other end */
@@ -2510,6 +2512,13 @@ int ssl3_send_client_key_exchange(SSL *s)
 			int ecdh_clnt_cert = 0;
 			int field_size = 0;
 
+			if (s->session->sess_cert == NULL) 
+				{
+				ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+				SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+				goto err;
+				}
+
 			/* Did we send out the client's
 			 * ECDH share for use in premaster
 			 * computation as part of client certificate?

+ 35 - 7
libs/openssl/ssl/s3_pkt.c

@@ -110,6 +110,7 @@
  */
 
 #include <stdio.h>
+#include <limits.h>
 #include <errno.h>
 #define USE_SOCKETS
 #include "ssl_locl.h"
@@ -580,10 +581,11 @@ int ssl3_do_compress(SSL *ssl)
 int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
 	{
 	const unsigned char *buf=buf_;
-	unsigned int tot,n,nw;
-	int i;
+	unsigned int n,nw;
+	int i,tot;
 
 	s->rwstate=SSL_NOTHING;
+	OPENSSL_assert(s->s3->wnum <= INT_MAX);
 	tot=s->s3->wnum;
 	s->s3->wnum=0;
 
@@ -598,6 +600,22 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
 			}
 		}
 
+	/* ensure that if we end up with a smaller value of data to write 
+	 * out than the the original len from a write which didn't complete 
+	 * for non-blocking I/O and also somehow ended up avoiding 
+	 * the check for this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as
+	 * it must never be possible to end up with (len-tot) as a large
+	 * number that will then promptly send beyond the end of the users
+	 * buffer ... so we trap and report the error in a way the user
+	 * will notice
+	 */
+	if (len < tot)
+		{
+		SSLerr(SSL_F_SSL3_WRITE_BYTES,SSL_R_BAD_LENGTH);
+		return(-1);
+		}
+
+
 	n=(len-tot);
 	for (;;)
 		{
@@ -641,9 +659,6 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
 	SSL3_BUFFER *wb=&(s->s3->wbuf);
 	SSL_SESSION *sess;
 
- 	if (wb->buf == NULL)
-		if (!ssl3_setup_write_buffer(s))
-			return -1;
 
 	/* first check if there is a SSL3_BUFFER still being written
 	 * out.  This will happen with non blocking IO */
@@ -659,6 +674,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
 		/* if it went, fall through and send more stuff */
 		}
 
+ 	if (wb->buf == NULL)
+		if (!ssl3_setup_write_buffer(s))
+			return -1;
+
 	if (len == 0 && !create_empty_fragment)
 		return 0;
 
@@ -1055,7 +1074,7 @@ start:
 				{
 				s->rstate=SSL_ST_READ_HEADER;
 				rr->off=0;
-				if (s->mode & SSL_MODE_RELEASE_BUFFERS)
+				if (s->mode & SSL_MODE_RELEASE_BUFFERS && s->s3->rbuf.left == 0)
 					ssl3_release_read_buffer(s);
 				}
 			}
@@ -1297,6 +1316,15 @@ start:
 			goto f_err;
 			}
 
+		if (!(s->s3->flags & SSL3_FLAGS_CCS_OK))
+			{
+			al=SSL_AD_UNEXPECTED_MESSAGE;
+			SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+			goto f_err;
+			}
+
+		s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
+
 		rr->length=0;
 
 		if (s->msg_callback)
@@ -1431,7 +1459,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
 
 	if (s->s3->tmp.key_block == NULL)
 		{
-		if (s->session == NULL) 
+		if (s->session == NULL || s->session->master_key_length == 0)
 			{
 			/* might happen if dtls1_read_bytes() calls this */
 			SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);

+ 17 - 16
libs/openssl/ssl/s3_srvr.c

@@ -673,6 +673,7 @@ int ssl3_accept(SSL *s)
 		case SSL3_ST_SR_CERT_VRFY_A:
 		case SSL3_ST_SR_CERT_VRFY_B:
 
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			/* we should decide if we expected this one */
 			ret=ssl3_get_cert_verify(s);
 			if (ret <= 0) goto end;
@@ -700,6 +701,7 @@ int ssl3_accept(SSL *s)
 
 		case SSL3_ST_SR_FINISHED_A:
 		case SSL3_ST_SR_FINISHED_B:
+			s->s3->flags |= SSL3_FLAGS_CCS_OK;
 			ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
 				SSL3_ST_SR_FINISHED_B);
 			if (ret <= 0) goto end;
@@ -770,7 +772,10 @@ int ssl3_accept(SSL *s)
 				s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #else
 				if (s->s3->next_proto_neg_seen)
+					{
+					s->s3->flags |= SSL3_FLAGS_CCS_OK;
 					s->s3->tmp.next_state=SSL3_ST_SR_NEXT_PROTO_A;
+					}
 				else
 					s->s3->tmp.next_state=SSL3_ST_SR_FINISHED_A;
 #endif
@@ -2097,6 +2102,11 @@ int ssl3_send_certificate_request(SSL *s)
 		s->init_num=n+4;
 		s->init_off=0;
 #ifdef NETSCAPE_HANG_BUG
+		if (!BUF_MEM_grow_clean(buf, s->init_num + 4))
+			{
+			SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
+			goto err;
+			}
 		p=(unsigned char *)s->init_buf->data + s->init_num;
 
 		/* do the header */
@@ -2813,6 +2823,8 @@ int ssl3_get_client_key_exchange(SSL *s)
 			unsigned char premaster_secret[32], *start;
 			size_t outlen=32, inlen;
 			unsigned long alg_a;
+			int Ttag, Tclass;
+			long Tlen;
 
 			/* Get our certificate private key*/
 			alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -2834,26 +2846,15 @@ int ssl3_get_client_key_exchange(SSL *s)
 					ERR_clear_error();
 				}
 			/* Decrypt session key */
-			if ((*p!=( V_ASN1_SEQUENCE| V_ASN1_CONSTRUCTED))) 
-				{
-				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
-				goto gerr;
-				}
-			if (p[1] == 0x81)
-				{
-				start = p+3;
-				inlen = p[2];
-				}
-			else if (p[1] < 0x80)
-				{
-				start = p+2;
-				inlen = p[1];
-				}
-			else
+			if (ASN1_get_object((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, n) != V_ASN1_CONSTRUCTED || 
+				Ttag != V_ASN1_SEQUENCE ||
+			 	Tclass != V_ASN1_UNIVERSAL) 
 				{
 				SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_DECRYPTION_FAILED);
 				goto gerr;
 				}
+			start = p;
+			inlen = Tlen;
 			if (EVP_PKEY_decrypt(pkey_ctx,premaster_secret,&outlen,start,inlen) <=0) 
 
 				{

+ 3 - 1
libs/openssl/ssl/ssl.h

@@ -553,7 +553,7 @@ struct ssl_session_st
 /* Allow initial connection to servers that don't support RI */
 #define SSL_OP_LEGACY_SERVER_CONNECT			0x00000004L
 #define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
+#define SSL_OP_TLSEXT_PADDING				0x00000010L
 #define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
 #define SSL_OP_SAFARI_ECDHE_ECDSA_BUG			0x00000040L
 #define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
@@ -562,6 +562,8 @@ struct ssl_session_st
 
 /* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
 #define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x0
+/* Refers to ancient SSLREF and SSLv2, retained for compatibility */
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x0
 
 /* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
  * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)

+ 1 - 0
libs/openssl/ssl/ssl3.h

@@ -388,6 +388,7 @@ typedef struct ssl3_buffer_st
 #define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
 #define TLS1_FLAGS_SKIP_CERT_VERIFY		0x0010
 #define TLS1_FLAGS_KEEP_HANDSHAKE		0x0020
+#define SSL3_FLAGS_CCS_OK			0x0080
  
 /* SSL3_FLAGS_SGC_RESTART_DONE is set when we
  * restart a handshake because of MS SGC and so prevents us

+ 4 - 0
libs/openssl/ssl/ssl_asn1.c

@@ -408,6 +408,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
 		if (os.length != 3)
 			{
 			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+			c.line=__LINE__;
 			goto err;
 			}
 		id=0x02000000L|
@@ -420,6 +421,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
 		if (os.length != 2)
 			{
 			c.error=SSL_R_CIPHER_CODE_WRONG_LENGTH;
+			c.line=__LINE__;
 			goto err;
 			}
 		id=0x03000000L|
@@ -429,6 +431,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
 	else
 		{
 		c.error=SSL_R_UNKNOWN_SSL_VERSION;
+		c.line=__LINE__;
 		goto err;
 		}
 	
@@ -521,6 +524,7 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
 	    if (os.length > SSL_MAX_SID_CTX_LENGTH)
 		{
 		c.error=SSL_R_BAD_LENGTH;
+		c.line=__LINE__;
 		goto err;
 		}
 	    else

+ 1 - 1
libs/openssl/ssl/ssl_err.c

@@ -541,7 +541,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
 {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME),"tlsv1 unrecognized name"},
 {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),"tlsv1 unsupported extension"},
 {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),"tls client cert req with anon cipher"},
-{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbearts"},
+{ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),"peer does not accept heartbeats"},
 {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING) ,"heartbeat request already pending"},
 {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),"tls illegal exporter label"},
 {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),"tls invalid ecpointformat list"},

+ 4 - 0
libs/openssl/ssl/ssl_lib.c

@@ -1349,6 +1349,10 @@ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
 
 	p=buf;
 	sk=s->session->ciphers;
+
+	if (sk_SSL_CIPHER_num(sk) == 0)
+		return NULL;
+
 	for (i=0; i<sk_SSL_CIPHER_num(sk); i++)
 		{
 		int n;

+ 2 - 6
libs/openssl/ssl/t1_enc.c

@@ -1048,14 +1048,10 @@ int tls1_mac(SSL *ssl, unsigned char *md, int send)
 	if (!stream_mac)
 		EVP_MD_CTX_cleanup(&hmac);
 #ifdef TLS_DEBUG
-printf("sec=");
-{unsigned int z; for (z=0; z<md_size; z++) printf("%02X ",mac_sec[z]); printf("\n"); }
 printf("seq=");
 {int z; for (z=0; z<8; z++) printf("%02X ",seq[z]); printf("\n"); }
-printf("buf=");
-{int z; for (z=0; z<5; z++) printf("%02X ",buf[z]); printf("\n"); }
 printf("rec=");
-{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
+{unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",rec->data[z]); printf("\n"); }
 #endif
 
 	if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER)
@@ -1185,7 +1181,7 @@ int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
 	if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST,
 		 TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) goto err1;
 
-	rv = tls1_PRF(s->s3->tmp.new_cipher->algorithm2,
+	rv = tls1_PRF(ssl_get_algorithm2(s),
 		      val, vallen,
 		      NULL, 0,
 		      NULL, 0,

+ 24 - 21
libs/openssl/ssl/t1_lib.c

@@ -617,6 +617,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
 
 #ifndef OPENSSL_NO_HEARTBEATS
 	/* Add Heartbeat extension */
+	if ((limit - ret - 4 - 1) < 0)
+		return NULL;
 	s2n(TLSEXT_TYPE_heartbeat,ret);
 	s2n(1,ret);
 	/* Set mode:
@@ -661,36 +663,35 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                 ret += el;
                 }
 #endif
-
-#ifdef TLSEXT_TYPE_padding
 	/* Add padding to workaround bugs in F5 terminators.
 	 * See https://tools.ietf.org/html/draft-agl-tls-padding-03
 	 *
 	 * NB: because this code works out the length of all existing
 	 * extensions it MUST always appear last.
 	 */
-	{
-	int hlen = ret - (unsigned char *)s->init_buf->data;
-	/* The code in s23_clnt.c to build ClientHello messages includes the
-	 * 5-byte record header in the buffer, while the code in s3_clnt.c does
-	 * not. */
-	if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
-		hlen -= 5;
-	if (hlen > 0xff && hlen < 0x200)
+	if (s->options & SSL_OP_TLSEXT_PADDING)
 		{
-		hlen = 0x200 - hlen;
-		if (hlen >= 4)
-			hlen -= 4;
-		else
-			hlen = 0;
+		int hlen = ret - (unsigned char *)s->init_buf->data;
+		/* The code in s23_clnt.c to build ClientHello messages
+		 * includes the 5-byte record header in the buffer, while
+		 * the code in s3_clnt.c does not.
+		 */
+		if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
+			hlen -= 5;
+		if (hlen > 0xff && hlen < 0x200)
+			{
+			hlen = 0x200 - hlen;
+			if (hlen >= 4)
+				hlen -= 4;
+			else
+				hlen = 0;
 
-		s2n(TLSEXT_TYPE_padding, ret);
-		s2n(hlen, ret);
-		memset(ret, 0, hlen);
-		ret += hlen;
+			s2n(TLSEXT_TYPE_padding, ret);
+			s2n(hlen, ret);
+			memset(ret, 0, hlen);
+			ret += hlen;
+			}
 		}
-	}
-#endif
 
 	if ((extdatalen = ret-p-2)== 0) 
 		return p;
@@ -845,6 +846,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
 	/* Add Heartbeat extension if we've received one */
 	if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED)
 		{
+		if ((limit - ret - 4 - 1) < 0)
+			return NULL;
 		s2n(TLSEXT_TYPE_heartbeat,ret);
 		s2n(1,ret);
 		/* Set mode:

+ 0 - 179
libs/zlib/zlib.vcxproj

@@ -1,179 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="UnityDebug|Win32">
-      <Configuration>UnityDebug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="UnityDebug|x64">
-      <Configuration>UnityDebug</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="UnityRelease|Win32">
-      <Configuration>UnityRelease</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="UnityRelease|x64">
-      <Configuration>UnityRelease</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="src\adler32.c" />
-    <ClCompile Include="src\compress.c" />
-    <ClCompile Include="src\crc32.c" />
-    <ClCompile Include="src\deflate.c" />
-    <ClCompile Include="src\gzclose.c" />
-    <ClCompile Include="src\gzlib.c" />
-    <ClCompile Include="src\gzread.c" />
-    <ClCompile Include="src\gzwrite.c" />
-    <ClCompile Include="src\infback.c" />
-    <ClCompile Include="src\inffast.c" />
-    <ClCompile Include="src\inflate.c" />
-    <ClCompile Include="src\inftrees.c" />
-    <ClCompile Include="src\trees.c" />
-    <ClCompile Include="src\uncompr.c" />
-    <ClCompile Include="src\zutil.c" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="src\crc32.h" />
-    <ClInclude Include="src\deflate.h" />
-    <ClInclude Include="src\gzguts.h" />
-    <ClInclude Include="src\inffast.h" />
-    <ClInclude Include="src\inffixed.h" />
-    <ClInclude Include="src\inflate.h" />
-    <ClInclude Include="src\inftrees.h" />
-    <ClInclude Include="src\trees.h" />
-    <ClInclude Include="src\zconf.h" />
-    <ClInclude Include="src\zlib.h" />
-    <ClInclude Include="src\zutil.h" />
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{E9F6071A-D2BC-471E-8899-5F49B024AA04}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>zlib</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|Win32'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|x64'" Label="Configuration">
-    <ConfigurationType>StaticLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|Win32'">
-    <OutDir>..\..\Temp\$(SolutionName)\$(Configuration)\x86\$(ProjectName)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|Win32'">
-    <IntDir>..\..\Temp\$(SolutionName)\$(Configuration)\x86\$(ProjectName)\</IntDir>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|Win32'">
-    <OutDir>..\..\Temp\$(SolutionName)\$(Configuration)\x86\$(ProjectName)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|Win32'">
-    <IntDir>..\..\Temp\$(SolutionName)\$(Configuration)\x86\$(ProjectName)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|x64'">
-    <OutDir>..\..\Temp\$(SolutionName)\$(Configuration)\x64\$(ProjectName)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|x64'">
-    <IntDir>..\..\Temp\$(SolutionName)\$(Configuration)\x64\$(ProjectName)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|x64'">
-    <OutDir>..\..\Temp\$(SolutionName)\$(Configuration)\x64\$(ProjectName)\</OutDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|x64'">
-    <IntDir>..\..\Temp\$(SolutionName)\$(Configuration)\x64\$(ProjectName)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='UnityDebug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>TurnOffAllWarnings</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <MinimalRebuild>false</MinimalRebuild>
-      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|Win32'">
-    <ClCompile>
-      <WarningLevel>TurnOffAllWarnings</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>Full</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <MinimalRebuild>false</MinimalRebuild>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='UnityRelease|x64'">
-    <ClCompile>
-      <WarningLevel>TurnOffAllWarnings</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>Full</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <MinimalRebuild>false</MinimalRebuild>
-      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-    </ClCompile>
-    <Link>
-      <SubSystem>Windows</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-    </Link>
-  </ItemDefinitionGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>

+ 2 - 2
readme_mfc.txt

@@ -46,10 +46,10 @@ https://forums.embarcadero.com/message.jspa?messageID=175480#175480
   - replace lines 357-367 of borland.mak with:
     OLECTL=
 
-  - change line 547 of borland.mak to read:
+  - change line 516 of borland.mak to read:
     $(LIBDIR)\$(GOAL).lib: $(D)\$(OBJS)
 
-  - change line 548 of borland.mak to read:
+  - change line 517 of borland.mak to read:
     # @-if exist $@ erase $@
 
   - change line 775 of arccore.cpp to read:

+ 1 - 1
source/Console.cbproj

@@ -41,7 +41,7 @@
 			<PackageImports>rtl.bpi;$(PackageImports)</PackageImports>
 			<ProjectType>CppConsoleApplication</ProjectType>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.0.3.0;InternalName=console;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.5.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Console interface for WinSCP;FileVersion=4.0.3.0;InternalName=console;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.com;ProductName=WinSCP;ProductVersion=5.5.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>4</VerInfo_MajorVer>
 			<VerInfo_Release>3</VerInfo_Release>

+ 1 - 1
source/DragExt.cbproj

@@ -42,7 +42,7 @@
 			<ProjectType>CppDynamicLibrary</ProjectType>
 			<VerInfo_DLL>true</VerInfo_DLL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.5.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=Drag&amp;Drop shell extension for WinSCP (32-bit);FileVersion=1.2.1.0;InternalName=dragext32;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=dragext.dll;ProductName=WinSCP;ProductVersion=5.5.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MinorVer>2</VerInfo_MinorVer>
 			<VerInfo_Release>1</VerInfo_Release>

+ 2 - 2
source/DragExt64.rc

@@ -1,6 +1,6 @@
 1 VERSIONINFO
 FILEVERSION 1,2,1,0
-PRODUCTVERSION 5,5,3,0
+PRODUCTVERSION 5,5,4,0
 FILEOS 0x4
 FILETYPE 0x2
 {
@@ -16,7 +16,7 @@ FILETYPE 0x2
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "dragext64.dll\0"
             VALUE "ProductName", "WinSCP\0"
-            VALUE "ProductVersion", "5.5.3.0\0"
+            VALUE "ProductVersion", "5.5.4.0\0"
             VALUE "ReleaseType", "stable\0"
             VALUE "WWW", "http://winscp.net/\0"
         }

+ 2 - 2
source/WinSCP.cbproj

@@ -54,11 +54,11 @@
 			<ProjectType>CppVCLApplication</ProjectType>
 			<UsingDelphiRTL>true</UsingDelphiRTL>
 			<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
-			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.5.3.0;InternalName=winscp;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.5.3.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
+			<VerInfo_Keys>CompanyName=Martin Prikryl;FileDescription=WinSCP: SFTP, FTP and SCP client;FileVersion=5.5.4.0;InternalName=winscp;LegalCopyright=(c) 2000-2014 Martin Prikryl;LegalTrademarks=;OriginalFilename=winscp.exe;ProductName=WinSCP;ProductVersion=5.5.4.0;ReleaseType=stable;WWW=http://winscp.net/</VerInfo_Keys>
 			<VerInfo_Locale>1033</VerInfo_Locale>
 			<VerInfo_MajorVer>5</VerInfo_MajorVer>
 			<VerInfo_MinorVer>5</VerInfo_MinorVer>
-			<VerInfo_Release>3</VerInfo_Release>
+			<VerInfo_Release>4</VerInfo_Release>
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Cfg_1)'!=''">
 			<BCC_DebugLineNumbers>true</BCC_DebugLineNumbers>

+ 13 - 1
source/components/UnixDirView.cpp

@@ -58,6 +58,18 @@ int __stdcall CompareDirectories(TListItem *Item1, TListItem *Item2)
   return 0;
 }
 //---------------------------------------------------------------------------
+int __fastcall CompareExtThenFull(const UnicodeString & Name1, const UnicodeString & Name2)
+{
+  UnicodeString Ext1 = UnixExtractFileExt(Name1);
+  UnicodeString Ext2 = UnixExtractFileExt(Name2);
+  int Result = AnsiCompareText(Ext1, Ext2);
+  if (Result == 0)
+  {
+    Result = AnsiCompareText(Name1, Name2);
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 #define DEFINE_COMPARE_FUNC_EX(PROPERTY, NAME, COMPAREFUNCFILE, COMPAREFUNCDIR, FALLBACK) \
   int __stdcall Compare ## NAME(TListItem *Item1, TListItem *Item2, TUnixDirView *DirView) \
   { \
@@ -94,7 +106,7 @@ DEFINE_COMPARE_FUNC(Owner, COMPARE_TOKEN);
 DEFINE_COMPARE_FUNC(Group, COMPARE_TOKEN);
 DEFINE_COMPARE_FUNC_EX(Extension, Extension, AnsiCompareText, COMPARE_DUMMY, AnsiCompareText);
 DEFINE_COMPARE_FUNC(LinkTo, AnsiCompareText);
-DEFINE_COMPARE_FUNC(TypeName, AnsiCompareText);
+DEFINE_COMPARE_FUNC_EX(TypeName, TypeName, AnsiCompareText, AnsiCompareText, CompareExtThenFull);
 //---------------------------------------------------------------------------
 #undef DEFINE_COMPARE_FUNC
 #undef COMPARE_NUMBER

+ 6 - 1
source/core/Common.cpp

@@ -1591,6 +1591,11 @@ bool __fastcall AdjustClockForDSTEnabled()
   return !DynamicDaylightTimeDisabled;
 }
 //---------------------------------------------------------------------------
+UnicodeString __fastcall StandardDatestamp()
+{
+  return FormatDateTime(L"yyyy'-'mm'-'dd", ConvertTimestampToUTC(Now()));
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall StandardTimestamp(const TDateTime & DateTime)
 {
   return FormatDateTime(L"yyyy'-'mm'-'dd'T'hh':'nn':'ss'.'zzz'Z'", ConvertTimestampToUTC(DateTime));
@@ -1656,7 +1661,7 @@ bool __fastcall RecursiveDeleteFile(const UnicodeString FileName, bool ToRecycle
   FileList[FileList.Length() - 1] = L'\0';
   FileList[FileList.Length()] = L'\0';
   Data.pFrom = FileList.c_str();
-  Data.pTo = L"";
+  Data.pTo = L"\0\0"; // this will actually give one null more than needed
   Data.fFlags = FOF_NOCONFIRMATION | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR |
     FOF_NOERRORUI | FOF_SILENT;
   if (ToRecycleBin)

+ 1 - 0
source/core/Common.h

@@ -151,6 +151,7 @@ __int64 __fastcall ConvertTimestampToUnixSafe(const FILETIME & FileTime,
 UnicodeString __fastcall FixedLenDateTimeFormat(const UnicodeString & Format);
 UnicodeString __fastcall StandardTimestamp(const TDateTime & DateTime);
 UnicodeString __fastcall StandardTimestamp();
+UnicodeString __fastcall StandardDatestamp();
 UnicodeString __fastcall GetTimeZoneLogString();
 bool __fastcall AdjustClockForDSTEnabled();
 int __fastcall CompareFileTime(TDateTime T1, TDateTime T2);

+ 8 - 0
source/core/CoreMain.cpp

@@ -59,6 +59,14 @@ bool __fastcall IsAuthenticationPrompt(TPromptKind Kind)
     (Kind == pkPassword) || (Kind == pkNewPassword);
 }
 //---------------------------------------------------------------------------
+bool __fastcall IsPasswordPrompt(TPromptKind Kind, TStrings * Prompts)
+{
+  return
+    (Prompts->Count == 1) && FLAGCLEAR(int(Prompts->Objects[0]), pupEcho) &&
+    ((Kind == pkPassword) || (Kind == pkPassphrase) || (Kind == pkKeybInteractive) ||
+     (Kind == pkTIS) || (Kind == pkCryptoCard));
+}
+//---------------------------------------------------------------------------
 void CoreInitialize()
 {
   Randomize();

+ 2 - 1
source/core/FtpFileSystem.cpp

@@ -1949,7 +1949,7 @@ void __fastcall TFTPFileSystem::ReadDirectory(TRemoteFileList * FileList)
         // further try without "-a" only as the server may not support it
         if (FListAll == asAuto)
         {
-          FTerminal->LogEvent(L"LIST with -a failed, walling back to pure LIST");
+          FTerminal->LogEvent(L"LIST with -a failed, will try pure LIST");
           if (!FTerminal->Active)
           {
             FTerminal->Reopen(ropNoReadDirectory);
@@ -3449,6 +3449,7 @@ bool __fastcall TFTPFileSystem::HandleAsynchRequestVerifyCertificate(
           break;
 
         case qaCancel:
+          FTerminal->Configuration->Usage->Inc(L"HostNotVerified");
           RequestResult = 0;
           break;
 

+ 1 - 0
source/core/Interface.h

@@ -99,6 +99,7 @@ enum TPromptKind
 enum TPromptUserParam { pupEcho = 0x01, pupRemember = 0x02 };
 
 bool __fastcall IsAuthenticationPrompt(TPromptKind Kind);
+bool __fastcall IsPasswordPrompt(TPromptKind Kind, TStrings * Prompts);
 //---------------------------------------------------------------------------
 typedef void __fastcall (__closure *TFileFoundEvent)
   (TTerminal * Terminal, const UnicodeString FileName, const TRemoteFile * File,

+ 7 - 4
source/core/Queue.cpp

@@ -2403,10 +2403,13 @@ void __fastcall TTerminalThread::WaitForUserAction(TUserAction * UserAction)
       SAFE_DESTROY(FException);
     }
 
-    if (DoCheckCancel)
-    {
-      CheckCancel();
-    }
+    // Contrary to a call before, this is unconditional,
+    // otherwise cancelling authentication won't work,
+    // if it is tried only after the last user action
+    // (what is common, when cancelling while waiting for
+    // resolving of unresolvable host name, where the last user action is
+    // "resolving hostname" information action)
+    CheckCancel();
   }
 }
 //---------------------------------------------------------------------------

+ 3 - 2
source/core/RemoteFiles.cpp

@@ -900,11 +900,12 @@ Boolean __fastcall TRemoteFile::GetIsInaccesibleDirectory() const
   {
     assert(Terminal);
     Result = !
-       (((Rights->RightUndef[TRights::rrOtherExec] != TRights::rsNo)) ||
+       (SameText(Terminal->UserName, L"root") ||
+        ((Rights->RightUndef[TRights::rrOtherExec] != TRights::rsNo)) ||
         ((Rights->Right[TRights::rrGroupExec] != TRights::rsNo) &&
          Terminal->Membership->Exists(Group.Name)) ||
         ((Rights->Right[TRights::rrUserExec] != TRights::rsNo) &&
-         (AnsiCompareText(Terminal->UserName, Owner.Name) == 0)));
+         SameText(Terminal->UserName, Owner.Name)));
   }
     else Result = False;
   return Result;

+ 3 - 1
source/core/SecureShell.cpp

@@ -2090,7 +2090,9 @@ void __fastcall TSecureShell::VerifyHostKey(UnicodeString Host, int Port,
 
     if (!Verified)
     {
-      Exception * E = new Exception(LoadStr(KEY_NOT_VERIFIED));
+      Configuration->Usage->Inc(L"HostNotVerified");
+
+      Exception * E = new Exception(MainInstructions(LoadStr(KEY_NOT_VERIFIED)));
       try
       {
         FUI->FatalError(E, FMTLOAD(HOSTKEY, (Fingerprint)));

+ 7 - 3
source/core/SessionInfo.cpp

@@ -959,8 +959,11 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
       }
       ADF(L"Ping type: %s, Ping interval: %d sec; Timeout: %d sec",
         (UnicodeString(PingTypes[PingType]), PingInterval, Data->Timeout));
-      ADF(L"Proxy: %s", (ProxyMethodList[Data->ProxyMethod]));
-      if (Data->ProxyMethod != ::pmNone)
+      ADF(L"Proxy: %s",
+        ((Data->FtpProxyLogonType != 0) ?
+          FORMAT(L"FTP proxy %d", (Data->FtpProxyLogonType)) :
+          UnicodeString(ProxyMethodList[Data->ProxyMethod])));
+      if ((Data->FtpProxyLogonType != 0) || (Data->ProxyMethod != ::pmNone))
       {
         ADF(L"HostName: %s (Port: %d); Username: %s; Passwd: %s",
           (Data->ProxyHost, Data->ProxyPort,
@@ -1003,7 +1006,7 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
           ((Data->DetectReturnVar ? UnicodeString(L"Autodetect") : Data->ReturnVar),
            BugFlags[Data->LookupUserGroups]));
         ADF(L"Shell: %s", ((Data->Shell.IsEmpty()? UnicodeString(L"default") : Data->Shell)));
-        ADF(L"EOL: %d, UTF: %d", (Data->EOLType, Data->NotUtf));
+        ADF(L"EOL: %d, UTF: %d", (Data->EOLType, Data->NotUtf)); // NotUtf duplicated in FTP branch
         ADF(L"Clear aliases: %s, Unset nat.vars: %s, Resolve symlinks: %s",
           (BooleanToEngStr(Data->ClearAliases), BooleanToEngStr(Data->UnsetNationalVars),
            BooleanToEngStr(Data->ResolveSymlinks)));
@@ -1024,6 +1027,7 @@ void __fastcall TSessionLog::DoAddStartupInfo(TSessionData * Data)
       }
       if (Data->FSProtocol == fsFTP)
       {
+        ADF(L"UTF: %d", (Data->NotUtf)); // duplicated in UsesSsh branch
         UnicodeString Ftps;
         switch (Data->Ftps)
         {

+ 33 - 27
source/core/Terminal.cpp

@@ -648,8 +648,8 @@ UnicodeString __fastcall TTerminal::DecryptPassword(const RawByteString & Passwo
 void __fastcall TTerminal::RecryptPasswords()
 {
   FSessionData->RecryptPasswords();
-  FPassword = EncryptPassword(DecryptPassword(FPassword));
-  FTunnelPassword = EncryptPassword(DecryptPassword(FTunnelPassword));
+  FRememberedPassword = EncryptPassword(DecryptPassword(FRememberedPassword));
+  FRememberedTunnelPassword = EncryptPassword(DecryptPassword(FRememberedTunnelPassword));
 }
 //---------------------------------------------------------------------------
 UnicodeString __fastcall TTerminal::ExpandFileName(UnicodeString Path,
@@ -1107,10 +1107,7 @@ bool __fastcall TTerminal::DoPromptUser(TSessionData * /*Data*/, TPromptKind Kin
   bool AResult = false;
 
 
-  bool PasswordPrompt =
-    (Prompts->Count == 1) && FLAGCLEAR(int(Prompts->Objects[0]), pupEcho) &&
-    ((Kind == pkPassword) || (Kind == pkPassphrase) || (Kind == pkKeybInteractive) ||
-     (Kind == pkTIS) || (Kind == pkCryptoCard));
+  bool PasswordPrompt = IsPasswordPrompt(Kind, Prompts);
   if (PasswordPrompt)
   {
     bool & PasswordTried =
@@ -1123,11 +1120,11 @@ bool __fastcall TTerminal::DoPromptUser(TSessionData * /*Data*/, TPromptKind Kin
       UnicodeString APassword;
       if (FTunnelOpening)
       {
-        APassword = GetPasswordSource()->TunnelPassword;
+        APassword = GetPasswordSource()->RememberedTunnelPassword;
       }
       else
       {
-        APassword = GetPasswordSource()->Password;
+        APassword = GetPasswordSource()->RememberedPassword;
       }
       Results->Strings[0] = APassword;
       if (!Results->Strings[0].IsEmpty())
@@ -1159,11 +1156,11 @@ bool __fastcall TTerminal::DoPromptUser(TSessionData * /*Data*/, TPromptKind Kin
       RawByteString EncryptedPassword = EncryptPassword(Results->Strings[0]);
       if (FTunnelOpening)
       {
-        GetPasswordSource()->FTunnelPassword = EncryptedPassword;
+        GetPasswordSource()->FRememberedTunnelPassword = EncryptedPassword;
       }
       else
       {
-        GetPasswordSource()->FPassword = EncryptedPassword;
+        GetPasswordSource()->FRememberedPassword = EncryptedPassword;
       }
     }
   }
@@ -2554,7 +2551,12 @@ TRemoteFileList * __fastcall TTerminal::ReadDirectoryListing(UnicodeString Direc
       while (Index < FileList->Count)
       {
         TRemoteFile * File = FileList->Files[Index];
-        if (!Mask.Matches(File->FileName))
+        TFileMasks::TParams Params;
+        Params.Size = File->Size;
+        Params.Modification = File->Modification;
+        // Have to use UnicodeString(), instead of L"", as with that
+        // overload with (UnicodeString, bool, bool, TParams*) wins
+        if (!Mask.Matches(File->FileName, false, UnicodeString(), &Params))
         {
           FileList->Delete(Index);
         }
@@ -4060,7 +4062,7 @@ bool __fastcall TTerminal::AllowLocalFileTransfer(UnicodeString FileName,
     WIN32_FIND_DATA FindData;
     HANDLE Handle;
     FILE_OPERATION_LOOP (FMTLOAD(FILE_NOT_EXISTS, (FileName)),
-      Handle = FindFirstFile(FileName.c_str(), &FindData);
+      Handle = FindFirstFile(ExcludeTrailingBackslash(FileName).c_str(), &FindData);
       if (Handle == INVALID_HANDLE_VALUE)
       {
         RaiseLastOSError();
@@ -5061,31 +5063,26 @@ const TFileSystemInfo & __fastcall TTerminal::GetFileSystemInfo(bool Retrieve)
 UnicodeString __fastcall TTerminal::GetPassword()
 {
   UnicodeString Result;
-  // FPassword is empty also when stored password was used
-  if (FPassword.IsEmpty())
+  // FRememberedPassword is empty also when stored password was used
+  if (FRememberedPassword.IsEmpty())
   {
     Result = SessionData->Password;
   }
   else
   {
-    Result = DecryptPassword(FPassword);
+    Result = RememberedPassword;
   }
   return Result;
 }
 //---------------------------------------------------------------------
-UnicodeString __fastcall TTerminal::GetTunnelPassword()
+UnicodeString __fastcall TTerminal::GetRememberedPassword()
 {
-  UnicodeString Result;
-  // FTunnelPassword is empty also when stored password was used
-  if (FTunnelPassword.IsEmpty())
-  {
-    Result = SessionData->TunnelPassword;
-  }
-  else
-  {
-    Result = DecryptPassword(FTunnelPassword);
-  }
-  return Result;
+  return DecryptPassword(FRememberedPassword);
+}
+//---------------------------------------------------------------------
+UnicodeString __fastcall TTerminal::GetRememberedTunnelPassword()
+{
+  return DecryptPassword(FRememberedTunnelPassword);
 }
 //---------------------------------------------------------------------
 bool __fastcall TTerminal::GetStoredCredentialsTried()
@@ -5387,6 +5384,15 @@ void __fastcall TTerminal::CollectUsage()
     Configuration->Usage->Inc(L"OpenedSessionsAdvanced");
   }
 
+  if (SessionData->ProxyMethod != ::pmNone)
+  {
+    Configuration->Usage->Inc(L"OpenedSessionsProxy");
+  }
+  if (SessionData->FtpProxyLogonType > 0)
+  {
+    Configuration->Usage->Inc(L"OpenedSessionsFtpProxy");
+  }
+
   FCollectFileSystemUsage = true;
 }
 //---------------------------------------------------------------------------

+ 6 - 4
source/core/Terminal.h

@@ -183,8 +183,8 @@ private:
   bool FReadingCurrentDirectory;
   bool * FClosedOnCompletion;
   TSessionStatus FStatus;
-  RawByteString FPassword;
-  RawByteString FTunnelPassword;
+  RawByteString FRememberedPassword;
+  RawByteString FRememberedTunnelPassword;
   TTunnelThread * FTunnelThread;
   TSecureShell * FTunnel;
   TSessionData * FTunnelData;
@@ -225,7 +225,8 @@ private:
   bool __fastcall GetResolvingSymlinks();
   bool __fastcall GetActive();
   UnicodeString __fastcall GetPassword();
-  UnicodeString __fastcall GetTunnelPassword();
+  UnicodeString __fastcall GetRememberedPassword();
+  UnicodeString __fastcall GetRememberedTunnelPassword();
   bool __fastcall GetStoredCredentialsTried();
   inline bool __fastcall InTransaction();
   static UnicodeString __fastcall SynchronizeModeStr(TSynchronizeMode Mode);
@@ -496,7 +497,8 @@ public:
   __property TStrings * FixedPaths = { read = GetFixedPaths };
   __property bool ResolvingSymlinks = { read = GetResolvingSymlinks };
   __property UnicodeString Password = { read = GetPassword };
-  __property UnicodeString TunnelPassword = { read = GetTunnelPassword };
+  __property UnicodeString RememberedPassword = { read = GetRememberedPassword };
+  __property UnicodeString RememberedTunnelPassword = { read = GetRememberedTunnelPassword };
   __property bool StoredCredentialsTried = { read = GetStoredCredentialsTried };
   __property TQueryUserEvent OnQueryUser = { read = FOnQueryUser, write = FOnQueryUser };
   __property TPromptUserEvent OnPromptUser = { read = FOnPromptUser, write = FOnPromptUser };

+ 1 - 1
source/core/Usage.h

@@ -18,6 +18,7 @@ public:
   void __fastcall Set(const UnicodeString & Key, bool Value);
   void __fastcall Inc(const UnicodeString & Key, int Increment = 1);
   void __fastcall SetMax(const UnicodeString & Key, int Value);
+  UnicodeString __fastcall Get(const UnicodeString & Key);
 
   void __fastcall UpdateCurrentVersion();
   void __fastcall Reset();
@@ -40,7 +41,6 @@ private:
   TStringList * FValues;
   bool FCollect;
 
-  UnicodeString __fastcall Get(const UnicodeString & Key);
   void __fastcall SetCollect(bool value);
   void __fastcall UpdateLastReport();
   void __fastcall Load(THierarchicalStorage * Storage,

+ 1 - 0
source/core/WebDAVFileSystem.cpp

@@ -14098,6 +14098,7 @@ webdav::error_t TWebDAVFileSystem::VerifyCertificate(
   switch (RequestResult)
   {
     case qaCancel:
+      FTerminal->Configuration->Usage->Inc(L"HostNotVerified");
       FFileTransferCancelled = true;
       FFileTransferAbort = ftaCancel;
       break;

+ 0 - 5
source/dragext/DragExt.cpp

@@ -551,11 +551,6 @@ STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN UnkOuter,
 
   CShellExt* ShellExt = new CShellExt();  //Create the CShellExt object
 
-  if (NULL == ShellExt)
-  {
-    return E_OUTOFMEMORY;
-  }
-
   return ShellExt->QueryInterface(Riid, PpvObj);
 }
 //---------------------------------------------------------------------------

+ 0 - 235
source/filezilla/AsyncSslSocketLayer.cpp

@@ -29,13 +29,6 @@ This class only has a couple of public functions:
   You can call this function only after receiving a layerspecific callback with the SSL_VERIFY_CERT 
   id. Set result to 1 if you trust the certificate and 0 if you don't trust it.
   nID has to be the priv_data element of the t_SslCertData structure and nCode has to be SSL_VERIFY_CERT.
-- CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state,
-			unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname,
-			unsigned char *email, CString& err);
-  Creates a new self-signed SSL certificate and stores it in the given file
-- SendRaw(const void* lpBuf, int nBufLen, int nFlags = 0)
-  Sends a raw, unencrypted message. This may be useful after successful initialization to tell the other
-  side that can use SSL.
 
 This layer sends some layerspecific notifications to your socket instance, you can handle them in
 OnLayerCallback of your socket class.
@@ -2149,234 +2142,6 @@ void CAsyncSslSocketLayer::PrintLastErrorMsg()
 	}
 }
 
-bool CAsyncSslSocketLayer::CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state,
-			unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname,
-			unsigned char *email, CString& err)
-{
-	// Certificate valid for a year
-	int days = 365;
-
-	CAsyncSslSocketLayer layer;
-	if (layer.InitSSL())
-	{
-		err = _T("Failed to initialize TLS library");
-		return false;
-	}
-
-	X509 *x;
-	EVP_PKEY *pk;
-	RSA *rsa;
-	X509_NAME *name = NULL;
-	
-	if ((pk = pEVP_PKEY_new()) == NULL)
-	{
-		err = _T("Could not create key object");
-		return false;
-	}
-
-	if ((x = pX509_new()) == NULL)
-	{
-		err = _T("Could not create certificate object");
-		return false;
-	}
-
-	rsa = pRSA_generate_key(bits, RSA_F4, 0/*callback*/, NULL);
-	
-	if (!pEVP_PKEY_assign(pk, EVP_PKEY_RSA, (char *)(rsa)))
-	{
-		err = _T("Failed to assign rsa key to key object");
-		return false;
-	}
-
-	rsa = NULL;
-
-	pX509_set_version(x,2);
-	pASN1_INTEGER_set(pX509_get_serialNumber(x), 0/*serial*/);
-	pX509_gmtime_adj(X509_get_notBefore(x),0);
-	pX509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
-	pX509_set_pubkey(x,pk);
-
-	name = pX509_get_subject_name(x);
-
-	/* This function creates and adds the entry, working out the
-	 * correct string type and performing checks on its length.
-	 * Normally we'd check the return value for errors...
-	 */
-	pX509_NAME_add_entry_by_txt(name, "CN",
-				MBSTRING_ASC, cname, -1, -1, 0);
-	pX509_NAME_add_entry_by_txt(name, "C",
-				MBSTRING_ASC, country, -1, -1, 0);
-	pX509_NAME_add_entry_by_txt(name, "ST",
-				MBSTRING_ASC, state, -1, -1, 0);
-	pX509_NAME_add_entry_by_txt(name, "L",
-				MBSTRING_ASC, locality, -1, -1, 0);
-	pX509_NAME_add_entry_by_txt(name, "O",
-				MBSTRING_ASC, organization, -1, -1, 0);
-	pX509_NAME_add_entry_by_txt(name, "OU",
-				MBSTRING_ASC, unit, -1, -1, 0);
-	pX509_NAME_add_entry_by_NID(name, NID_pkcs9_emailAddress,
-				MBSTRING_ASC, email, -1, -1, 0);
-
-	/* Its self signed so set the issuer name to be the same as the
- 	 * subject.
-	 */
-	pX509_set_issuer_name(x,name);
-
-	if (!pX509_sign(x, pk, pEVP_sha1()))
-	{
-		err = _T("Failed to sign certificate");
-		return false;
-	}
-
-	// Write key and certificate to file
-	// We use a memory bio, since the OpenSSL functions accepting a filepointer 
-	// do crash for no obvious reason.
-
-#ifndef _UNICODE
-	FILE* file = fopen(filename, "w+");
-#else
-	FILE* file = _wfopen(filename, _T("w+"));
-#endif
-
-	if (!file)
-	{
-		err = _T("Failed to open output file");
-		return false;
-	}
-
-	BIO* bio = pBIO_new(pBIO_s_mem());
-#ifdef MPEXT
-	pPEM_ASN1_write_bio((i2d_of_void*)pi2d_PrivateKey, (((pk)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA), bio, (char *)pk, NULL, NULL, 0, NULL, NULL);
-	pPEM_ASN1_write_bio((i2d_of_void*)pi2d_X509, PEM_STRING_X509, bio, (char *)x, NULL, NULL, 0, NULL, NULL);
-#else
-	pPEM_ASN1_write_bio((int (*)())pi2d_PrivateKey, (((pk)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA), bio, (char *)pk, NULL, NULL, 0, NULL, NULL);
-	pPEM_ASN1_write_bio((int (*)())pi2d_X509, PEM_STRING_X509, bio, (char *)x, NULL, NULL, 0, NULL, NULL);
-#endif
-	
-	char buffer[1001];
-	int len;
-	while ((len = pBIO_read(bio, buffer, 1000)) > 0)
-	{
-		buffer[len] = 0;
-		fprintf(file, buffer);
-	}
-
-	fclose(file);
-
-	pX509_free(x);
-	pEVP_PKEY_free(pk);
-
-	pBIO_free(bio);
-
-	layer.UnloadSSL();
-
-	return true;
-}
-
-int CAsyncSslSocketLayer::SetCertKeyFile(const char* cert, const char* key, const char* pass, CString* error /*=0*/)
-{
-	int res = InitSSL();
-	if (res)
-		return res;
-
-	m_sCriticalSection.Lock();
-	
-	if (!m_ssl_ctx)
-	{
-		// Create new context
-		if (!(m_ssl_ctx = pSSL_CTX_new( pSSLv23_method())))
-		{
-			m_sCriticalSection.Unlock();
-			return SSL_FAILURE_INITSSL;
-		}
-		m_contextRefCount[m_ssl_ctx] = 1;
-	}
-
-	pSSL_CTX_set_default_passwd_cb(m_ssl_ctx, pem_passwd_cb);
-	pSSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
-
-	if (pass)
-	{
-		size_t len = strlen(pass);
-		m_pKeyPassword = new char[len + 1];
-		strcpy(m_pKeyPassword, pass);
-	}
-	else
-	{
-		delete [] m_pKeyPassword;
-		m_pKeyPassword = 0;
-	}
-
-	if (pSSL_CTX_use_certificate_chain_file(m_ssl_ctx, cert) <= 0)
-	//if (pSSL_CTX_use_certificate_file(m_ssl_ctx, cert, SSL_FILETYPE_PEM) <= 0)
-	{
-		if (error)
-			*error = _T("Could not load certificate file.");
-		m_sCriticalSection.Unlock();
-		return SSL_FAILURE_VERIFYCERT;
-	}
-
-	if (pSSL_CTX_use_PrivateKey_file(m_ssl_ctx, key, SSL_FILETYPE_PEM) <= 0)
-	{
-		if (error)
-			*error = _T("Could not load key file.");
-		m_sCriticalSection.Unlock();
-		return SSL_FAILURE_VERIFYCERT;
-	}
-
-	if (!pSSL_CTX_check_private_key(m_ssl_ctx))
-	{
-		if (error)
-			*error = _T("Private key does not match the certificate public key.");
-		m_sCriticalSection.Unlock();
-		return SSL_FAILURE_VERIFYCERT;
-	}
-
-	m_sCriticalSection.Unlock();
-
-	return 0;
-}
-
-int CAsyncSslSocketLayer::SendRaw(const void* lpBuf, int nBufLen, int nFlags)
-{
-	if (!m_bUseSSL)
-	{
-		SetLastError(WSANOTINITIALISED);
-		return SOCKET_ERROR;
-	}
-
-	if (!lpBuf)
-		return 0;
-	
-	if (m_nNetworkError)
-	{
-		SetLastError(m_nNetworkError);
-		return SOCKET_ERROR;
-	}
-	if (m_nShutDown)
-	{
-		SetLastError(WSAESHUTDOWN);
-		return SOCKET_ERROR;
-	}
-	if (m_nNetworkSendBufferLen)
-	{
-		SetLastError(WSAEINPROGRESS);
-		return SOCKET_ERROR;
-	}
-	if (!nBufLen)
-		return 0;
-
-	if (m_nNetworkSendBufferMaxLen < nBufLen)
-		m_nNetworkSendBufferMaxLen = nBufLen;
-	delete [] m_pNetworkSendBuffer;
-	m_pNetworkSendBuffer = new char[m_nNetworkSendBufferMaxLen];
-	memcpy(m_pNetworkSendBuffer, lpBuf, nBufLen);
-	m_nNetworkSendBufferLen = nBufLen;
-	TriggerEvent(FD_WRITE, 0);
-
-	return nBufLen;
-}
-
 void CAsyncSslSocketLayer::TriggerEvents()
 {
 	size_t pending = pBIO_ctrl_pending(m_nbio);

+ 0 - 13
source/filezilla/AsyncSslSocketLayer.h

@@ -30,13 +30,6 @@ This class only has a couple of public functions:
   You can call this function only after receiving a layerspecific callback with the SSL_VERIFY_CERT 
   id. Set result to 1 if you trust the certificate and 0 if you don't trust it.
   nID has to be the priv_data element of the t_SslCertData structure and nCode has to be SSL_VERIFY_CERT.
-- CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state,
-			unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname,
-			unsigned char *email, CString& err);
-  Creates a new self-signed SSL certificate and stores it in the given file
-- SendRaw(const void* lpBuf, int nBufLen, int nFlags = 0)
-  Sends a raw, unencrypted message. This may be useful after successful initialization to tell the other
-  side that can use SSL.
 
 This layer sends some layerspecific notifications to your socket instance, you can handle them in
 OnLayerCallback of your socket class.
@@ -155,12 +148,6 @@ public:
 		bool sessionreuse, int minTlsVersion, int maxTlsVersion,
 		void* pContext = 0);
 
-	static bool CreateSslCertificate(LPCTSTR filename, int bits, unsigned char* country, unsigned char* state,
-			unsigned char* locality, unsigned char* organization, unsigned char* unit, unsigned char* cname,
-			unsigned char *email, CString& err);
-
-	int SetCertKeyFile(const char* cert, const char* key, const char* pass, CString* error = 0);
-
 	// Send raw text, useful to send a confirmation after the ssl connection
 	// has been initialized
 	int SendRaw(const void* lpBuf, int nBufLen, int nFlags = 0);

+ 0 - 1
source/filezilla/FileZillaApi.cpp

@@ -86,7 +86,6 @@ int CFileZillaApi::Init(CApiLog * pParent, CFileZillaTools * pTools)
 	m_pMainThread->m_nInternalMessageID=m_nInternalMessageID;
 	m_pMainThread->m_nReplyMessageID=m_nReplyMessageID;
 	m_pMainThread->m_hOwnerWnd=m_hOwnerWnd;
-	m_pMainThread->m_hOwnerWnd=m_hOwnerWnd;
 	m_pMainThread->m_pTools=pTools;
 
 #ifndef MPEXT

+ 18 - 1
source/filezilla/FtpListResult.cpp

@@ -1336,11 +1336,28 @@ BOOL CFtpListResult::parseAsMlsd(const char *line, const int linelen, t_director
 		{
 			if (!value.CompareNoCase(_T("dir")))
 				direntry.dir = TRUE;
+			// This is syntax used by proftpd by default
+			// http://www.proftpd.org/docs/modules/mod_facts.html
+			// They claim it's the correct one.
+			// See also
+			// http://www.rfc-editor.org/errata_search.php?rfc=3659&eid=1500
+			else if (!value.Left(15).CompareNoCase(_T("OS.unix=symlink")))
+			{
+				direntry.dir = TRUE;
+				direntry.bLink = TRUE;
+				// actually symlink target should not be included in this syntax,
+				// but just in case some servers do.
+				if ((value.GetLength() > 16) && (value[15] == ':'))
+					direntry.linkTarget = value.Mid(16);
+			}
+			// This is syntax shown in RFC 3659 section 7.7.4 "A More Complex Example"
+			// Type=OS.unix=slink:/foobar;Perm=;Unique=keVO1+4G4; foobar
+			// https://tools.ietf.org/html/rfc3659
 			else if (!value.Left(13).CompareNoCase(_T("OS.unix=slink")))
 			{
 				direntry.dir = TRUE;
 				direntry.bLink = TRUE;
-				if (value[13] == ':' && value[14] != 0)
+				if ((value.GetLength() > 14) && (value[13] == ':'))
 					direntry.linkTarget = value.Mid(14);
 			}
 			else if (!value.CompareNoCase(_T("cdir")) ||

+ 1 - 4
source/forms/Authenticate.cpp

@@ -227,10 +227,7 @@ bool __fastcall TAuthenticateForm::PromptUser(TPromptKind Kind, UnicodeString Na
     bool ShowSessionRememberPasswordPanel = false;
     bool ShowSavePasswordPanel = false;
     TSessionData * Data = NULL;
-    bool PasswordPrompt =
-      ((Kind == pkPassword) || (Kind == pkTIS) || (Kind == pkCryptoCard) ||
-       (Kind == pkKeybInteractive)) &&
-      (Prompts->Count == 1) && FLAGCLEAR(int(Prompts->Objects[0]), pupEcho);
+    bool PasswordPrompt = IsPasswordPrompt(Kind, Prompts);
     if (PasswordPrompt && StoredCredentialsTried)
     {
       Data = StoredSessions->FindSame(FSessionData);

+ 13 - 5
source/forms/CustomScpExplorer.cpp

@@ -3799,7 +3799,10 @@ void __fastcall TCustomScpExplorerForm::ApplicationMinimize(TObject * /*Sender*/
   {
     UpdateTrayIcon();
     FTrayIcon->Visible = true;
-    ShowWindow(Handle, SW_HIDE);
+    if (Visible)
+    {
+      ShowWindow(Handle, SW_HIDE);
+    }
   }
 }
 //---------------------------------------------------------------------------
@@ -3808,7 +3811,10 @@ void __fastcall TCustomScpExplorerForm::ApplicationRestore(TObject * /*Sender*/)
   if (FTrayIcon->Visible)
   {
     FTrayIcon->Visible = false;
-    ShowWindow(Handle, SW_SHOW);
+    if (Visible)
+    {
+      ShowWindow(Handle, SW_SHOW);
+    }
   }
 }
 //---------------------------------------------------------------------------
@@ -3837,7 +3843,7 @@ void __fastcall TCustomScpExplorerForm::RestoreApp()
       SetAppIconic(true);
     }
   }
-  Application->Restore();
+  ::ApplicationRestore();
   Application->BringToFront();
 }
 //---------------------------------------------------------------------------
@@ -6942,9 +6948,11 @@ void __fastcall TCustomScpExplorerForm::GetTransferPresetAutoSelectData(
 //---------------------------------------------------------------------------
 void __fastcall TCustomScpExplorerForm::TransferPresetAutoSelect()
 {
-  if (FAllowTransferPresetAutoSelect)
+  // Terminal can be null when we are changing local directory implicitly,
+  // because it has been deleted, while no session is connected
+  // (Login dialog is open)
+  if (FAllowTransferPresetAutoSelect && (Terminal != NULL))
   {
-    assert(Terminal != NULL);
     TCopyParamRuleData Data;
     GetTransferPresetAutoSelectData(Data);
 

+ 1 - 1
source/forms/FileFind.cpp

@@ -306,7 +306,7 @@ void __fastcall TFileFindDialog::MinimizeButtonClick(TObject * Sender)
 //---------------------------------------------------------------------------
 void __fastcall TFileFindDialog::GlobalMinimize(TObject * /*Sender*/)
 {
-  Application->Minimize();
+  ApplicationMinimize();
   FMinimizedByMe = true;
 }
 //---------------------------------------------------------------------------

+ 16 - 1
source/forms/Login.cpp

@@ -2564,6 +2564,21 @@ TTreeNode * __fastcall TLoginDialog::GetNextNode(TTreeNode * Node, bool Reverse)
   return Node;
 }
 //---------------------------------------------------------------------------
+static bool __fastcall ContainsTextSemiCaseSensitive(
+  const UnicodeString & Text, const UnicodeString & SubText)
+{
+  bool Result;
+  if (AnsiLowerCase(SubText) == SubText)
+  {
+    Result = ContainsText(Text, SubText);
+  }
+  else
+  {
+    Result = ContainsStr(Text, SubText);
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 TTreeNode * __fastcall TLoginDialog::SearchSite(const UnicodeString & Text,
   bool AllowExpanding, bool SkipCurrent, bool Reverse)
 {
@@ -2596,7 +2611,7 @@ TTreeNode * __fastcall TLoginDialog::SearchSite(const UnicodeString & Text,
           (Parent->Expanded || AllowExpanding);
         Parent = Parent->Parent;
       }
-      if (Eligible && ContainsText(Node->Text, Text))
+      if (Eligible && ContainsTextSemiCaseSensitive(Node->Text, Text))
       {
         return Node;
       }

+ 2 - 2
source/forms/MessageDlg.cpp

@@ -783,7 +783,7 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
     LOGFONT AFont;
     COLORREF AColor;
 
-    memset(&AFont, sizeof(AFont), 0);
+    memset(&AFont, 0, sizeof(AFont));
     if (GetThemeFont(Theme, NULL, TEXT_MAININSTRUCTION, 0, TMT_FONT, &AFont) == S_OK)
     {
       MainInstructionFont = CreateFontIndirect(&AFont);
@@ -793,7 +793,7 @@ TForm * __fastcall TMessageForm::Create(const UnicodeString & Msg,
       MainInstructionColor = (TColor)AColor;
     }
 
-    memset(&AFont, sizeof(AFont), 0);
+    memset(&AFont, 0, sizeof(AFont));
     if (GetThemeFont(Theme, NULL, TEXT_INSTRUCTION, 0, TMT_FONT, &AFont) == S_OK)
     {
       InstructionFont = CreateFontIndirect(&AFont);

+ 1 - 1
source/forms/Progress.cpp

@@ -469,7 +469,7 @@ void __fastcall TProgressForm::CancelOperation()
 //---------------------------------------------------------------------------
 void __fastcall TProgressForm::GlobalMinimize(TObject * /*Sender*/)
 {
-  Application->Minimize();
+  ApplicationMinimize();
   FMinimizedByMe = true;
 }
 //---------------------------------------------------------------------------

+ 1 - 1
source/forms/ScpCommander.cpp

@@ -1777,7 +1777,7 @@ void __fastcall TScpCommanderForm::LocalPathComboUpdateDrives()
     FLocalPathComboBoxPaths->AddObject(GetPersonalFolder(),
       (TObject *)DriveInfo->SpecialFolder[CSIDL_PERSONAL]->ImageIndex);
     Strings->Add(LoadStr(SPECIAL_FOLDER_DESKTOP));
-    FLocalPathComboBoxPaths->AddObject(DriveInfo->SpecialFolder[CSIDL_DESKTOP]->Location,
+    FLocalPathComboBoxPaths->AddObject(GetDesktopFolder(),
       (TObject *)DriveInfo->SpecialFolder[CSIDL_DESKTOP]->ImageIndex);
 
     for (TDrive Drive = FirstDrive; Drive <= LastDrive; Drive++)

+ 2 - 2
source/forms/Synchronize.cpp

@@ -394,7 +394,7 @@ void __fastcall TSynchronizeDialog::Stop()
   if (IsApplicationMinimized() && FMinimizedByMe)
   {
     FMinimizedByMe = false;
-    Application->Restore();
+    ApplicationRestore();
     Application->BringToFront();
   }
 }
@@ -406,7 +406,7 @@ void __fastcall TSynchronizeDialog::MinimizeButtonClick(TObject * Sender)
 //---------------------------------------------------------------------------
 void __fastcall TSynchronizeDialog::GlobalMinimize(TObject * /*Sender*/)
 {
-  Application->Minimize();
+  ApplicationMinimize();
   FMinimizedByMe = true;
 }
 //---------------------------------------------------------------------------

+ 1 - 1
source/forms/SynchronizeProgress.cpp

@@ -114,7 +114,7 @@ void __fastcall TSynchronizeProgressForm::MinimizeButtonClick(
 //---------------------------------------------------------------------------
 void __fastcall TSynchronizeProgressForm::GlobalMinimize(TObject * /*Sender*/)
 {
-  Application->Minimize();
+  ApplicationMinimize();
   FMinimizedByMe = true;
 }
 //---------------------------------------------------------------------------

+ 11 - 2
source/packages/filemng/DirView.pas

@@ -1708,7 +1708,9 @@ begin
                 else
               begin
                 if (AttrExcludeMask and Srec.Attr and SysUtils.faHidden) <> 0 then
-                  Inc(FHiddenCount);
+                  Inc(FHiddenCount)
+                else
+                  Inc(FFilteredCount);
               end;
             end;
             DosError := FindNext(SRec);
@@ -1980,7 +1982,9 @@ begin
                       else
                     begin
                       if (AttrExcludeMask and Srec.Attr and SysUtils.faHidden) <> 0 then
-                        Inc(FHiddenCount);
+                        Inc(FHiddenCount)
+                      else
+                        Inc(FFilteredCount);
                     end;
                   end
                     else
@@ -2079,6 +2083,11 @@ begin
           end;
         end; {Finally}
       end;
+
+      if Assigned(FDriveView) and Assigned(TDriveView(FDriveView).Selected) then
+      begin
+        TDriveView(FDriveView).ValidateCurrentDirectoryIfNotMonitoring;
+      end;
     end;
   end;
 end; {Reload2}

+ 12 - 0
source/packages/filemng/DriveView.pas

@@ -342,6 +342,7 @@ type
     function WatchThreadActive(Drive: TDrive): Boolean; overload;
     function NodeWatched(Node: TTreeNode): Boolean; virtual;
 {$ENDIF}
+    procedure ValidateCurrentDirectoryIfNotMonitoring;
 
     (* Modified Events: *)
     procedure GetImageIndex(Node: TTreeNode); override;
@@ -1151,6 +1152,8 @@ begin
       if (not Assigned(FPrevSelected)) or (not FPrevSelected.HasAsParent(Node)) then
         Node.Expand(False);
       FPrevSelected := Node;
+
+      ValidateCurrentDirectoryIfNotMonitoring;
     end;
   end;
 
@@ -1901,6 +1904,15 @@ begin
         ValidateDirectory(RootNode);
 end;
 
+procedure TDriveView.ValidateCurrentDirectoryIfNotMonitoring;
+begin
+  if Assigned(Selected) and
+     not Assigned(DriveStatus[GetDriveToNode(Selected)].DiscMonitor) then
+  begin
+    ValidateDirectory(Selected);
+  end;
+end;
+
 procedure TDriveView.ValidateDirectoryEx(Node: TTreeNode; Recurse: TRecursiveScan;
   NewDirs: Boolean);
 var

+ 26 - 0
source/packages/my/NortonLikeListView.pas

@@ -35,6 +35,7 @@ type
     FLButtonDownShiftState: TShiftState;
     FLButtonDownPos: TPoint;
     FLastSelectMethod: TSelectMethod;
+    FPendingInternalFocus: TListItem;
     procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
     procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
     procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
@@ -77,6 +78,7 @@ type
     function GetSelCount: Integer; override;
     procedure DDBeforeDrag;
     function CanEdit(Item: TListItem): Boolean; override;
+    procedure DoEnter; override;
   public
     { Public declarations }
     constructor Create(AOwner: TComponent); override;
@@ -209,6 +211,7 @@ begin
   FUpdatingSelection := 0;
   FFocusingItem := False;
   FLastSelectMethod := smNoneYet;
+  FPendingInternalFocus := nil;
   // On Windows Vista, native GetNextItem for selection stops working once we
   // disallow deselecting any item (see ExCanChange).
   // So we need to manage selection state ourselves
@@ -305,6 +308,10 @@ begin
   begin
     ItemUnselected(Item, -1);
   end;
+  if FPendingInternalFocus = Item then
+  begin
+    FPendingInternalFocus := nil;
+  end;
   FLastDeletedItem := Item;
   inherited;
   FLastDeletedItem := nil;
@@ -690,11 +697,30 @@ begin
       FDontSelectItem := PDontSelectItem;
       FDontUnSelectItem := PDontUnSelectItem;
     end;
+    FPendingInternalFocus := nil;
+  end
+    else
+  begin
+    FPendingInternalFocus := Item;
   end;
   if ItemFocused <> Item then
     ItemFocused := Item;
 end;
 
+procedure TCustomNortonLikeListView.DoEnter;
+begin
+  inherited;
+
+  if Assigned(FPendingInternalFocus) then
+  begin
+    if FPendingInternalFocus = ItemFocused then
+    begin
+      FocusItem(FPendingInternalFocus);
+    end;
+    FPendingInternalFocus := nil;
+  end;
+end;
+
 procedure TCustomNortonLikeListView.SelectAll(Mode: TSelectMode; Exclude: TListItem);
 var
   Index: Integer;

+ 12 - 0
source/packages/my/PasTools.pas

@@ -37,6 +37,7 @@ function ControlHasRecreationPersistenceData(Control: TControl): Boolean;
 
 function IsAppIconic: Boolean;
 procedure SetAppIconic(Value: Boolean);
+procedure SetAppMainForm(Value: TForm);
 
 type
   TControlScrollBeforeUpdate = procedure(ObjectToValidate: TObject) of object;
@@ -307,6 +308,7 @@ type
   public
     function IsAppIconic: Boolean;
     procedure SetAppIconic(Value: Boolean);
+    procedure SetMainForm(Value: TForm);
   end;
 
 function TApplicationHelper.IsAppIconic: Boolean;
@@ -319,6 +321,11 @@ begin
   Self.FAppIconic := Value;
 end;
 
+procedure TApplicationHelper.SetMainForm(Value: TForm);
+begin
+  Self.FMainForm := Value;
+end;
+
 function IsAppIconic: Boolean;
 begin
   Result := Application.IsAppIconic;
@@ -329,6 +336,11 @@ begin
   Application.SetAppIconic(Value);
 end;
 
+procedure SetAppMainForm(Value: TForm);
+begin
+  Application.SetMainForm(Value);
+end;
+
 
   { TCustomControlScrollOnDragOver }
 

+ 8 - 3
source/packages/my/TcpIp.pas

@@ -346,6 +346,10 @@ end;
 function TTcpIp.CreateSocket: TSocket;
 begin
   Result := Winsock.Socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
+  if Result = INVALID_SOCKET then
+  begin
+    raise ESocketError.Create(WSAGetLastError);
+  end;
 end;
 
 procedure TTcpIp.BindSocket(var Socket: TSocket; OutPortMin, OutPortMax: Word);
@@ -372,6 +376,7 @@ procedure TTcpIp.ConnectSocket(var Socket: TSocket; SocketNumber: SmallInt;
   IpAddress: LongInt);
 var
   RemoteAddress: TSockAddr;
+  Error: Integer;
 begin
   with RemoteAddress do
   begin
@@ -383,7 +388,8 @@ begin
   if Winsock.Connect(Socket,RemoteAddress,
        SizeOf(RemoteAddress)) = SOCKET_ERROR then
   begin
-    if Winsock.WSAGetLastError <> WSAEWouldBlock then
+    Error := Winsock.WSAGetLastError;
+    if Error <> WSAEWouldBlock then
     begin
       CloseSocket(Socket);
       if Assigned(FTracer) then
@@ -391,6 +397,7 @@ begin
         FTracer('Failed to open output socket '+IntToStr(SocketNumber)+' to host '+
           Ip2String(IpAddress), tt_socket);
       end;
+      raise ESocketError.Create(Error);
     end
   end
     else
@@ -551,8 +558,6 @@ begin
   if IpAddress = INVALID_IP_ADDRESS then
     raise ETcpIpError.Create('Couldn''t resolve hostname ' + FHostname);
   OpenSocketOut(FSocket, FSocketNumber, IpAddress);
-  if FSocket = INVALID_SOCKET then
-    raise ESocketError.Create(WSAGetLastError);
   FEof := False;
   FLoggedIn := True;
 end;

+ 1 - 1
source/packages/tb2k/LICENSE.txt

@@ -1,4 +1,4 @@
-All files included in the Toolbar2000 archive are Copyright (C) 1998-2004
+All files included in the Toolbar2000 archive are Copyright (C) 1998-2005
 Jordan Russell.
 
 Use and/or distribution of the files requires compliance with the

+ 1 - 0
source/resource/HelpWin.h

@@ -54,5 +54,6 @@
 #define HELP_COLOR                   "task_connections#session_color"
 #define HELP_DRAGEXT_TARGET_NOT_INSTALLED "dragext"
 #define HELP_DRAGEXT_TARGET_UNKNOWN  HELP_DRAGEXT_TARGET_NOT_INSTALLED
+#define HELP_KEY_TYPE_UNSUPPORTED    "ui_puttygen#other_formats"
 
 #endif // TextsWin

+ 7 - 1
source/resource/TextsCore1.rc

@@ -189,6 +189,12 @@ BEGIN
   TLS_CERT_DECODE_ERROR, "Error decoding TLS/SSL certificate (%s)."
   FIND_FILE_ERROR, "Error retrieving file list for \"%s\"."
   CERT_NAME_MISMATCH, "Certificate was not issued for this server. You might be connecting to a server that is pretending to be \"%s\"."
+  CERT_ERR_CERT_CHAIN_TOO_LONG, "Certificate chain too long."
+  CERT_ERR_CERT_HAS_EXPIRED, "Certificate has expired."
+  CERT_ERR_CERT_NOT_YET_VALID, "Certificate is not yet valid."
+  CERT_ERR_CERT_REJECTED, "Certificate rejected."
+  CERT_ERR_CERT_SIGNATURE_FAILURE, "Certificate signature failure."
+  CERT_ERR_CERT_UNTRUSTED, "Certificate not trusted."
 
   CORE_CONFIRMATION_STRINGS, "CORE_CONFIRMATION"
   CONFIRM_PROLONG_TIMEOUT3, "Host is not communicating for %d seconds.\n\nWait for another %0:d seconds?"
@@ -372,7 +378,7 @@ BEGIN
   FILEZILLA_URL, "http://filezilla-project.org/"
   OPENSSL_BASED_ON, "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit %s."
   OPENSSL_COPYRIGHT, "Copyright © 1998-2014 The OpenSSL Project"
-  OPENSSL_VERSION, "1.0.1g"
+  OPENSSL_VERSION, "1.0.1h"
   OPENSSL_URL, "http://www.openssl.org/"
   PUTTY_LICENSE_URL, "http://www.chiark.greenend.org.uk/~sgtatham/putty/licence.html"
   MAIN_MSG_TAG, "**"

+ 1 - 1
source/resource/TextsWin1.rc

@@ -92,7 +92,7 @@ BEGIN
         UNINSTALL_CLEANUP, "Do you want to cleanup data stored by the application on this computer?"
         EXIT_ON_COMPLETION, "%s\n\nDo you want to close application?"
         DISCONNECT_ON_COMPLETION, "%%s\n\nDo you want to terminate %d remaining session(s) and close the application?"
-        PENDING_QUEUE_ITEMS2, "**There are still some background transfers in queue. Do you want to disconnect anyway?**\n \nWarning: Pressing 'OK' will terminate all transfers immediatelly."
+        PENDING_QUEUE_ITEMS2, "**There are still some background transfers in queue. Do you want to disconnect anyway?**\n \nWarning: Pressing 'OK' will terminate all transfers immediately."
         PERFORM_ON_COMMAND_SESSION2, "**Do you want to open separate shell session?**\n\nCurrent %s session does not support command you request. Separate shell session may be opened to process the command.\n \nNote: The server must provide Unix-like shell and the shell must use same path syntax as current %s session."
         PENDING_EDITORS, "There are some opened files. Please close them before exiting application.\n \nBeware: If you ignore this message, opened files may remain in temporary directory."
         CLEANTEMP_CONFIRM2, "**Do you want to delete past temporary folders?**\n\nWinSCP has found %d temporary folders, which it has probably created in past. These folders may contain files previously edited or downloaded.\n\nYou may also open the folders to review their content and to delete them yourself."

+ 56 - 14
source/windows/GUITools.cpp

@@ -259,6 +259,33 @@ bool __fastcall SpecialFolderLocation(int PathID, UnicodeString & Path)
   return false;
 }
 //---------------------------------------------------------------------------
+static UnicodeString __fastcall GetWineHomeFolder()
+{
+  UnicodeString Result;
+
+  UnicodeString WineHostHome = GetEnvironmentVariable(L"WINE_HOST_HOME");
+  if (!WineHostHome.IsEmpty())
+  {
+    Result = L"Z:" + FromUnixPath(WineHostHome);
+  }
+  else
+  {
+    // Should we use WinAPI GetUserName() instead?
+    UnicodeString UserName = GetEnvironmentVariable(L"USERNAME");
+    if (!UserName.IsEmpty())
+    {
+      Result = L"Z:\\home\\" + UserName;
+    }
+  }
+
+  if (!DirectoryExists(Result))
+  {
+    Result = L"";
+  }
+
+  return Result;
+}
+//---------------------------------------------------------------------------
 UnicodeString __fastcall GetPersonalFolder()
 {
   UnicodeString Result;
@@ -266,26 +293,41 @@ UnicodeString __fastcall GetPersonalFolder()
 
   if (IsWine())
   {
-    UnicodeString WineHostHome = GetEnvironmentVariable(L"WINE_HOST_HOME");
-    if (!WineHostHome.IsEmpty())
+    UnicodeString WineHome = GetWineHomeFolder();
+
+    if (!WineHome.IsEmpty())
     {
-      UnicodeString WineHome = L"Z:" + ToUnixPath(WineHostHome);
-      if (DirectoryExists(WineHome))
+      // if at least home exists, use it
+      Result = WineHome;
+
+      // but try to go deeper to "Documents"
+      UnicodeString WineDocuments =
+        IncludeTrailingBackslash(WineHome) + L"Documents";
+      if (DirectoryExists(WineDocuments))
       {
-        Result = WineHome;
+        Result = WineDocuments;
       }
     }
-    else
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
+UnicodeString __fastcall GetDesktopFolder()
+{
+  UnicodeString Result;
+  SpecialFolderLocation(CSIDL_DESKTOPDIRECTORY, Result);
+
+  if (IsWine())
+  {
+    UnicodeString WineHome = GetWineHomeFolder();
+
+    if (!WineHome.IsEmpty())
     {
-      // Should we use WinAPI GetUserName() instead?
-      UnicodeString UserName = GetEnvironmentVariable(L"USERNAME");
-      if (!UserName.IsEmpty())
+      UnicodeString WineDesktop =
+        IncludeTrailingBackslash(WineHome) + L"Desktop";
+      if (DirectoryExists(WineHome))
       {
-        UnicodeString WineHome = L"Z:\\home\\" + UserName;
-        if (DirectoryExists(WineHome))
-        {
-          Result = WineHome;
-        }
+        Result = WineDesktop;
       }
     }
   }

+ 1 - 0
source/windows/GUITools.h

@@ -31,6 +31,7 @@ void __fastcall OpenSessionInPutty(const UnicodeString PuttyPath,
   TSessionData * SessionData, UnicodeString UserName, UnicodeString Password);
 bool __fastcall SpecialFolderLocation(int PathID, UnicodeString & Path);
 UnicodeString __fastcall GetPersonalFolder();
+UnicodeString __fastcall GetDesktopFolder();
 UnicodeString __fastcall ItemsFormatString(const UnicodeString SingleItemFormat,
   const UnicodeString MultiItemsFormat, int Count, const UnicodeString FirstItem);
 UnicodeString __fastcall ItemsFormatString(const UnicodeString SingleItemFormat,

+ 5 - 0
source/windows/Setup.cpp

@@ -823,10 +823,15 @@ void __fastcall QueryUpdates()
       {
         case ctAuto:
           AutodetectProxyUrl(Proxy);
+          if (!Proxy.IsEmpty())
+          {
+            Configuration->Usage->Inc(L"UpdateProxyAutodetected");
+          }
           break;
 
         case ctProxy:
           Proxy = FORMAT(L"%s:%d", (Updates.ProxyHost, Updates.ProxyPort));
+          Configuration->Usage->Inc(L"UpdateProxyManual");
           break;
       }
       CheckForUpdatesHTTP->Proxy = Proxy;

+ 16 - 1
source/windows/TerminalManager.cpp

@@ -370,11 +370,25 @@ bool __fastcall TTerminalManager::ConnectActiveTerminal()
     WinConfiguration->AddSessionToJumpList(ActiveTerminal->SessionData->SessionName);
   }
 
+  FAuthenticationCancelled = false;
   bool Result = ConnectActiveTerminalImpl(false);
 
-  if (!Result)
+  UnicodeString DateStamp = StandardDatestamp();
+  if (Result)
+  {
+    if (Configuration->Usage->Get(L"OpenedSessionsFailedLastDate") == DateStamp)
+    {
+      Configuration->Usage->Inc(L"OpenedSessionsFailedRecovered");
+    }
+  }
+  else
   {
     Configuration->Usage->Inc(L"OpenedSessionsFailed");
+    Configuration->Usage->Set(L"OpenedSessionsFailedLastDate", DateStamp);
+    if (FAuthenticationCancelled)
+    {
+      Configuration->Usage->Inc(L"OpenedSessionsFailedAfterCancel");
+    }
   }
 
   if (Result && WinConfiguration->AutoOpenInPutty && CanOpenInPutty())
@@ -903,6 +917,7 @@ void __fastcall TTerminalManager::AuthenticateFormCancel(TObject * Sender)
       TerminalThread->Cancel();
     }
   }
+  FAuthenticationCancelled = true;
 }
 //---------------------------------------------------------------------------
 TAuthenticateForm * __fastcall TTerminalManager::MakeAuthenticateForm(

+ 1 - 0
source/windows/TerminalManager.h

@@ -101,6 +101,7 @@ private:
   ITaskbarList3 * FTaskbarList;
   int FAuthenticating;
   void * FBusyToken;
+  bool FAuthenticationCancelled;
 
   bool __fastcall ConnectActiveTerminalImpl(bool Reopen);
   bool __fastcall ConnectActiveTerminal();

+ 24 - 2
source/windows/Tools.cpp

@@ -901,14 +901,17 @@ static void __fastcall DoVerifyKey(
     FileName = ExpandEnvironmentVariables(FileName);
     TKeyType Type = KeyType(FileName);
     UnicodeString Message;
+    UnicodeString HelpKeyword = HELP_LOGIN_KEY_TYPE;
     switch (Type)
     {
       case ktOpenSSH:
         Message = FMTLOAD(KEY_TYPE_UNSUPPORTED, (FileName, L"OpenSSH SSH-2"));
+        HelpKeyword = HELP_KEY_TYPE_UNSUPPORTED;
         break;
 
       case ktSSHCom:
         Message = FMTLOAD(KEY_TYPE_UNSUPPORTED, (FileName, L"ssh.com SSH-2"));
+        HelpKeyword = HELP_KEY_TYPE_UNSUPPORTED;
         break;
 
       case ktSSH1:
@@ -937,8 +940,9 @@ static void __fastcall DoVerifyKey(
 
     if (!Message.IsEmpty())
     {
+      Configuration->Usage->Inc(L"PrivateKeySelectErrors");
       if (MessageDialog(Message, qtWarning, qaIgnore | qaAbort,
-           HELP_LOGIN_KEY_TYPE) == qaAbort)
+           HelpKeyword) == qaAbort)
       {
         Abort();
       }
@@ -970,7 +974,25 @@ static bool __fastcall GetProxyUrlFromIE(UnicodeString & Proxy)
   {
     if (IEProxyInfo.lpszProxy != NULL)
     {
-      Proxy = IEProxyInfo.lpszProxy;
+      UnicodeString IEProxy = IEProxyInfo.lpszProxy;
+      Proxy = L"";
+      while (Proxy.IsEmpty() && !IEProxy.IsEmpty())
+      {
+        UnicodeString Str = ::CutToChar(IEProxy, L';', true);
+        if (Str.Pos(L"=") == 0)
+        {
+          Proxy = Str;
+        }
+        else
+        {
+          UnicodeString Protocol = ::CutToChar(Str, L'=', true);
+          if (SameText(Protocol, L"http"))
+          {
+            Proxy = Str;
+          }
+        }
+      }
+
       GlobalFree(IEProxyInfo.lpszProxy);
       Result = true;
     }

+ 46 - 0
source/windows/WinInterface.cpp

@@ -995,6 +995,52 @@ void __fastcall CallGlobalMinimizeHandler(TObject * Sender)
   }
 }
 //---------------------------------------------------------------------------
+static void __fastcall DoApplicationMinimizeRestore(bool Minimize)
+{
+  // WORKAROUND
+  // When main window is hidden (command-line operation),
+  // we do not want it to be shown by TApplication.Restore,
+  // so we temporarily detach it from an application.
+  // Probably not really necessary for minimizing phase,
+  // but we do it for consistency anyway.
+  TForm * MainForm = Application->MainForm;
+  bool RestoreMainForm = false;
+  if (ALWAYS_TRUE(MainForm != NULL) &&
+      !MainForm->Visible)
+  {
+    SetAppMainForm(NULL);
+    RestoreMainForm = true;
+  }
+  try
+  {
+    if (Minimize)
+    {
+      Application->Minimize();
+    }
+    else
+    {
+      Application->Restore();
+    }
+  }
+  __finally
+  {
+    if (RestoreMainForm)
+    {
+      SetAppMainForm(MainForm);
+    }
+  }
+}
+//---------------------------------------------------------------------------
+void __fastcall ApplicationMinimize()
+{
+  DoApplicationMinimizeRestore(true);
+}
+//---------------------------------------------------------------------------
+void __fastcall ApplicationRestore()
+{
+  DoApplicationMinimizeRestore(false);
+}
+//---------------------------------------------------------------------------
 bool __fastcall IsApplicationMinimized()
 {
   // VCL help recommends handling Application->OnMinimize/OnRestore

+ 2 - 0
source/windows/WinInterface.h

@@ -410,6 +410,8 @@ void __fastcall SetGlobalMinimizeHandler(TCustomForm * Form, TNotifyEvent OnMini
 void __fastcall ClearGlobalMinimizeHandler(TNotifyEvent OnMinimize);
 void __fastcall CallGlobalMinimizeHandler(TObject * Sender);
 bool __fastcall IsApplicationMinimized();
+void __fastcall ApplicationMinimize();
+void __fastcall ApplicationRestore();
 void __fastcall WinInitialize();
 
 void __fastcall ShowNotification(TTerminal * Terminal, const UnicodeString & Str,