From dde1f7a1adb976ffa3761b2280f0fde77da3d797 Mon Sep 17 00:00:00 2001 From: Mikael Svenson Date: Mon, 3 Jun 2019 08:57:59 +0200 Subject: [PATCH] #2101 Cleanup private key only for file or pem based certificate login --- CHANGELOG.md | 5 ++++ Commands/Base/SPOnlineConnectionHelper.cs | 35 +++++++++-------------- Commands/Utilities/CertificateHelper.cs | 14 +++++++++ 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 088b745b9..50a661280 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). +## [Unreleased] + +### Changed +- Cleanup private key only for file or pem based certificate login (#2101) + ## [3.9.1905.3 - May 2019 Intermediate Release 3] ### Changed diff --git a/Commands/Base/SPOnlineConnectionHelper.cs b/Commands/Base/SPOnlineConnectionHelper.cs index 121c87343..10c5c280a 100644 --- a/Commands/Base/SPOnlineConnectionHelper.cs +++ b/Commands/Base/SPOnlineConnectionHelper.cs @@ -365,23 +365,11 @@ internal static SPOnlineConnection InitiateAzureADNativeApplicationConnection(Ur internal static SPOnlineConnection InitiateAzureADAppOnlyConnection(Uri url, string clientId, string tenant, string certificatePath, SecureString certificatePassword, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, PSHost host, bool disableTelemetry, bool skipAdminCheck = false, AzureEnvironment azureEnvironment = AzureEnvironment.Production) { - var authManager = new OfficeDevPnP.Core.AuthenticationManager(); - var context = PnPClientContext.ConvertFrom(authManager.GetAzureADAppOnlyAuthenticatedContext(url.ToString(), clientId, tenant, certificatePath, certificatePassword, azureEnvironment), retryCount, retryWait * 1000); - var connectionType = ConnectionType.OnPrem; - if (url.Host.ToUpperInvariant().EndsWith("SHAREPOINT.COM")) - { - connectionType = ConnectionType.O365; - } - if (skipAdminCheck == false) - { - if (IsTenantAdminSite(context)) - { - connectionType = ConnectionType.TenantAdmin; - } - } - var spoConnection = new SPOnlineConnection(context, connectionType, minimalHealthScore, retryCount, retryWait, null, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.AADAppOnly); - spoConnection.ConnectionMethod = Model.ConnectionMethod.AzureADAppOnly; - return spoConnection; + X509Certificate2 certificate = CertificateHelper.GetCertificateFromPath(certificatePath, certificatePassword); + + return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, + retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, + certificate, true); } internal static SPOnlineConnection InitiateAzureADAppOnlyConnection(Uri url, string clientId, string tenant, @@ -391,7 +379,8 @@ internal static SPOnlineConnection InitiateAzureADAppOnlyConnection(Uri url, str AzureEnvironment azureEnvironment = AzureEnvironment.Production) { X509Certificate2 certificate = CertificateHelper.GetCertificatFromStore(thumbprint); - return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate); + + return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate, false); } internal static SPOnlineConnection InitiateAzureADAppOnlyConnection(Uri url, string clientId, string tenant, string certificatePEM, string privateKeyPEM, SecureString certificatePassword, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, PSHost host, bool disableTelemetry, bool skipAdminCheck = false, AzureEnvironment azureEnvironment = AzureEnvironment.Production) @@ -399,12 +388,12 @@ internal static SPOnlineConnection InitiateAzureADAppOnlyConnection(Uri url, str string password = new System.Net.NetworkCredential(string.Empty, certificatePassword).Password; X509Certificate2 certificate = CertificateHelper.GetCertificateFromPEMstring(certificatePEM, privateKeyPEM, password); - return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate); + return InitiateAzureAdAppOnlyConnectionWithCert(url, clientId, tenant, minimalHealthScore, retryCount, retryWait, requestTimeout, tenantAdminUrl, host, disableTelemetry, skipAdminCheck, azureEnvironment, certificate, true); } private static SPOnlineConnection InitiateAzureAdAppOnlyConnectionWithCert(Uri url, string clientId, string tenant, int minimalHealthScore, int retryCount, int retryWait, int requestTimeout, string tenantAdminUrl, PSHost host, bool disableTelemetry, - bool skipAdminCheck, AzureEnvironment azureEnvironment, X509Certificate2 certificate) + bool skipAdminCheck, AzureEnvironment azureEnvironment, X509Certificate2 certificate, bool certificateFromFile) { var authManager = new OfficeDevPnP.Core.AuthenticationManager(); var clientContext = @@ -426,11 +415,15 @@ private static SPOnlineConnection InitiateAzureAdAppOnlyConnectionWithCert(Uri u } } - CleanupCryptoMachineKey(certificate); + if (certificateFromFile) + { + CleanupCryptoMachineKey(certificate); + } var spoConnection = new SPOnlineConnection(context, connectionType, minimalHealthScore, retryCount, retryWait, null, url.ToString(), tenantAdminUrl, PnPPSVersionTag, host, disableTelemetry, InitializationType.AADAppOnly); spoConnection.ConnectionMethod = ConnectionMethod.AzureADAppOnly; + return spoConnection; } diff --git a/Commands/Utilities/CertificateHelper.cs b/Commands/Utilities/CertificateHelper.cs index 0ba472212..48cd6a75e 100644 --- a/Commands/Utilities/CertificateHelper.cs +++ b/Commands/Utilities/CertificateHelper.cs @@ -127,6 +127,20 @@ internal static X509Certificate2 GetCertificateFromPEMstring(string publicCert, return certificate; } + internal static X509Certificate2 GetCertificateFromPath(string certificatePath, SecureString certificatePassword) + { + var certFile = System.IO.File.OpenRead(certificatePath); + var certificateBytes = new byte[certFile.Length]; + certFile.Read(certificateBytes, 0, (int)certFile.Length); + var certificate = new X509Certificate2( + certificateBytes, + certificatePassword, + X509KeyStorageFlags.Exportable | + X509KeyStorageFlags.MachineKeySet | + X509KeyStorageFlags.PersistKeySet); + return certificate; + } + #region certificate manipulation private static void EncodeLength(BinaryWriter stream, int length) {