diff --git a/CHANGELOG.md b/CHANGELOG.md index 11baf915d..9fd38feb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,21 @@ This is the changelog for this fork of OMI. It documents the changes in each of the tagged releases +## 2.2.0 - TBD + ++ Created universal builds to be used across the various nix distributions + + `glibc` is based on CentOS 7 and is designed for most GNU/Linux distributions, EL/Debian/Arch/etc + + `musl` is based on Alpine 3 and is designed for busybox/Linux distributions, Alpine + + `macOS` is based on macOS + + These universal builds is designed to reduce the number of `libmi` builds being distributed and automatically support future distribution releases as they are made ++ Deprecated the `-Distribution` parameter of `Install-WSMan` as it no longer does anything ++ Removed support for Debian 8 and Fedora 31 due to the age of the distribution ++ Added initial support for OpenSSL 3.x for glibc, musl, and macOS based distributions ++ Added support for using OpenSSL installed from `port` if `brew` is not used on macOS + + One of them must be installed but you are no longer limited to just `brew` ++ Use `@loader_path` on macOS instead of `@executable_path` for loading `libmi` to support relative paths from the library itself rather than `pwsh` ++ `Register-TrustedCertificate` will now create a file with a determinable name to avoid creating duplicate entries + ## 2.1.0 - 2020-11-24 + Added the following distributions diff --git a/PSWSMan/PSWSMan.psd1 b/PSWSMan/PSWSMan.psd1 index d141560ab..e84260dc8 100644 --- a/PSWSMan/PSWSMan.psd1 +++ b/PSWSMan/PSWSMan.psd1 @@ -1,5 +1,5 @@ @{ - ModuleVersion = '2.1.0' + ModuleVersion = '2.2.0' RootModule = 'PSWSMan' GUID = '92ec96bf-3ff4-41b2-8694-cd3ee636d3fd' Author = 'Jordan Borean' diff --git a/PSWSMan/PSWSMan.psm1 b/PSWSMan/PSWSMan.psm1 index 922857e0a..cf2edb81c 100644 --- a/PSWSMan/PSWSMan.psm1 +++ b/PSWSMan/PSWSMan.psm1 @@ -23,38 +23,140 @@ class X509CertificateChainAttribute : ArgumentTransformationAttribute { } } -Add-Type -Namespace PSWSMan -Name Native -MemberDefinition @' -[StructLayout(LayoutKind.Sequential)] -public class PWSH_Version -{ - public Int32 Major; - public Int32 Minor; - public Int32 Build; - public Int32 Revision; +Add-Type -TypeDefinition @' +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; - public static explicit operator Version(PWSH_Version v) +namespace PSWSMan +{ + public class Native { - return new Version(v.Major, v.Minor, v.Build, v.Revision); - } -} + [StructLayout(LayoutKind.Sequential)] + public class PWSH_Version + { + public Int32 Major; + public Int32 Minor; + public Int32 Build; + public Int32 Revision; + + public static explicit operator Version(PWSH_Version v) + { + return new Version(v.Major, v.Minor, v.Build, v.Revision); + } + } + + [DllImport("libc")] + public static extern void setenv(string name, string value); + + [DllImport("libc")] + public static extern void unsetenv(string name); + + [DllImport("libc")] + public static extern IntPtr gnu_get_libc_version(); + + [DllImport("libmi")] + public static extern void MI_Version_Info(PWSH_Version version); + + [DllImport("libpsrpclient")] + public static extern void PSRP_Version_Info(PWSH_Version version); + + private delegate uint OpenSSL_version_num_ptr(); + + public static uint OpenSSL_version_num(string[] libSSLPaths) + { + IntPtr lib = LoadLibrary(libSSLPaths); + if (lib == IntPtr.Zero) + return 0; + + try + { + // OpenSSL_version_num was introduced in 1.1.x, use SSLeay for older versions. + string[] functionNames = {"OpenSSL_version_num", "SSLeay"}; + + foreach (string name in functionNames) + { + IntPtr functionAddr = IntPtr.Zero; + try + { + functionAddr = NativeLibrary.GetExport(lib, name); + } + catch (EntryPointNotFoundException) {} + + if (functionAddr == IntPtr.Zero) + continue; + + var function = (OpenSSL_version_num_ptr)Marshal.GetDelegateForFunctionPointer( + functionAddr, typeof(OpenSSL_version_num_ptr)); + return function(); + } + + return 0; + } + finally { + NativeLibrary.Free(lib); + } + } + + private delegate IntPtr OpenSSL_version_ptr(int t); -[DllImport("libc")] -public static extern void setenv(string name, string value); + public static string OpenSSL_version(string[] libSSLPaths, int t) + { + IntPtr lib = LoadLibrary(libSSLPaths); + if (lib == IntPtr.Zero) + return null; + + try + { + IntPtr functionAddr = IntPtr.Zero; + + try + { + functionAddr = NativeLibrary.GetExport(lib, "OpenSSL_version"); + } + catch (EntryPointNotFoundException) {} -[DllImport("libc")] -public static extern void unsetenv(string name); + if (functionAddr == IntPtr.Zero) + return null; -[DllImport("libmi")] -public static extern void MI_Version_Info(PWSH_Version version); + var function = (OpenSSL_version_ptr)Marshal.GetDelegateForFunctionPointer( + functionAddr, typeof(OpenSSL_version_ptr)); -[DllImport("libpsrpclient")] -public static extern void PSRP_Version_Info(PWSH_Version version); + return Marshal.PtrToStringAuto(function(t)); + } + finally { + NativeLibrary.Free(lib); + } + } + + private static IntPtr LoadLibrary(string[] loadPaths) + { + foreach(string path in loadPaths) + { + IntPtr handle = IntPtr.Zero; + try + { + if (NativeLibrary.TryLoad(path, out handle)) + return handle; + } + catch + { + // TryLoad can actually through an exception so we just ignore it and continue on. + continue; + } + } + + return IntPtr.Zero; + } + } +} '@ Function exec { <# .SYNOPSIS - Wraps a native exec call in a function so it can be set with '-ErrorAction SilentlyContinue'. + Wraps a native exec call and output as separate streams for manual handling #> [CmdletBinding()] param ( @@ -67,10 +169,40 @@ Function exec { $Arguments ) - (&$FilePath @Arguments | Set-Variable output) 2>&1 | Set-Variable err - $output - if ($err) { - $err | Write-Error + $psi = [Diagnostics.ProcessStartInfo]@{ + FileName = $FilePath + Arguments = ($Arguments -join ' ') + RedirectStandardError = $true + RedirectStandardOutput = $true + } + $proc = [Diagnostics.Process]::Start($psi) + + $stdout = [Text.StringBuilder]::new() + $stderr = [Text.StringBuilder]::new() + $eventParams = @{ + InputObject = $proc + Action = { + if (-not [System.String]::IsNullOrEmpty($EventArgs.Data)) { + $Event.MessageData.AppendLine($EventArgs.Data) + } + } + } + $stdoutEvent = Register-ObjectEvent @eventParams -EventName 'OutputDataReceived' -MessageData $stdout + $stderrEvent = Register-ObjectEvent @eventParams -EventName 'ErrorDataReceived' -MessageData $stderr + + $proc.BeginOutputReadLine() + $proc.BeginErrorReadLine() + + $proc.WaitForExit() + + Unregister-Event -SourceIdentifier $stdoutEvent.Name + Unregister-Event -SourceIdentifier $stderrEvent.Name + + + [PSCustomObject]@{ + Stdout = $stdout.ToString() + Stderr = $stderr.ToString() + ExitCode = $proc.ExitCode } } @@ -116,6 +248,255 @@ Function unsetenv { } } +Function Get-OpenSSLInfo { + <# + .SYNOPSIS + Gets the OpenSSL version and SSL dir that is currently installed. + #> + [CmdletBinding()] + param ( + [String[]] + $LibSSL + ) + + $distribution = Get-Distribution + + $sslPaths = if ($LibSSL) { + $LibSSL + } + elseif ($distribution -eq 'macOS') { + @( + 'libssl', + 'libssl.dylib', + 'libssl.1.1.dylib', + 'libssl.10.dylib', + 'libssl.1.0.0.dylib', + 'libssl.3.dylib' + ) + } + else { + @( + 'libssl', + 'libssl.so', + 'libssl.so.1.1', + 'libssl.so.10', + 'libssl.so.1.0.0', + 'libssl.so.3' + ) + } + Write-Verbose -Message "Getting OpenSSL version for '$($sslPaths -join "', '")'" + + $versionNum = [PSWSMan.Native]::OpenSSL_version_num($sslPaths) + + # MNNFFPPS: major minor fix patch status + # For major=1 patch refers to the letter as a number, e.g. 1 == 'a', 2 == 'b', etc + # We don't care about status + $major = ($versionNum -band 0xF0000000) -shr 28 + $minor = ($versionNum -band 0x0FF00000) -shr 20 + $fix = ($versionNum -band 0x000FF000) -shr 12 + $patch = ($versionNum -band 0x00000FF0) -shr 4 + + $version = [Version]::new($major, $minor, $fix, $patch) + + $sslDir = [PSWSMan.Native]::OpenSSL_version($sslPaths, 4) # OPENSSL_DIR + $sslDir = if ($sslDir) { + $sslDir | + Select-String -Pattern 'OPENSSLDIR:\s+[\"|''](.*)[\"|'']$' | + ForEach-Object -Process { $_.Matches[0].Groups[1].Value } | + Select-Object -First 1 + } + + [PSCustomObject]@{ + Version = $version + SSLDir = $sslDir + } +} + +Function Get-MacOSOpenSSL { + <# + .SYNOPSIS + Gets the libcrypto and libssl paths to use on macOS. It gets the path from the brew install openssl package and + falls back to the port install package. We cannot use the LibreSSL version distributed by Apple as that is old + and isn't compatible with libmi. + #> + [CmdletBinding()] + param () + + $libCrypto = $null + $libSSL = $null + + if (Get-Command -Name brew -CommandType Application -ErrorAction SilentlyContinue) { + $brewInfo = exec brew --prefix openssl + $msg = "Attempting to get OpenSSL info with brew --prefix openssl`nSTDOUT: {0}`nSTDERR: {1}`nRC: {2}" -f ( + $brewInfo.Stdout, $brewInfo.Stderr, $brewInfo.ExitCode) + Write-Verbose -Message $msg + + if ($brewInfo.ExitCode -eq 0) { + $brewLibCrypto = Join-Path -Path $brewInfo.Stdout.Trim() lib libcrypto.dylib + if (Test-Path -LiteralPath $brewLibCrypto) { + Write-Verbose "Brew libcrypto exists at '$brewLibCrypto'" + $libCrypto = $brewLibCrypto + } + + $brewLibSSL = Join-Path -Path $brewInfo.Stdout.Trim() lib libssl.dylib + if (Test-Path -LiteralPath $brewLibSSL) { + Write-Verbose "Brew libssl exists at '$brewLibCrypto'" + $libSSL = $brewLibSSL` + } + } + } + + if ( + -not ($libCrypto -and $libSSL) -and + (Get-Command -Name port -CommandType Application -ErrorAction SilentlyContinue) + ) { + $portInfo = exec port contents openssl + Write-Verbose -Message "Attempting to get OpenSSL info port contents openssl" + + $portLibSSL = $null + $portLibCrypto = $null + + $portInfo.Stdout -split '\r?\n' | ForEach-Object -Process { + $line = $_.Trim() + if (-not $line.StartsWith('/') -or ($portLibSSL -and $portLibCrypto)) { + return + } + + if ($line -like '*/libssl.dylib') { + $portLibSSL = $line + } + elseif ($line -like '*/libcrypto.dylib') { + $portLibCrypto = $line + } + } + + if ($portLibCrypto -and (Test-Path -LiteralPath $portLibCrypto)) { + Write-Verbose "Port libcrypto exists at '$portLibCrypto'" + $libCrypto = $portLibCrypto + } + + if ($portLibSSL -and (Test-Path -LiteralPath $portLibSSL)) { + Write-Verbose "Port libssl exists at '$portLibSSL'" + $libSSL = $portLibSSL + } + } + + [PSCustomObject]@{ + LibCrypto = $libCrypto + LibSSL = $libSSL + } +} + +Function Get-HostInfo { + <# + .SYNOPSIS + Gets the host info that selects the native libraries to install. + + .NOTES + Currently we support the following C Standard Libraries: + macOS + glibc + musl + + Each support OpenSSL 1.1.x and 3.x and glibc also supports 1.0.x. + #> + [CmdletBinding()] + param () + + $distribution = Get-Distribution + + switch ($distribution) { + macOS { + $libDetails = Get-MacOSOpenSSL + + if ($libDetails.LibCrypto -and $libDetails.LibSSL) { + $opensslVersion = (Get-OpenSSLInfo -LibSSL $libDetails.LibSSL).Version + Write-Verbose -Message ("OpenSSL Version: Major {0} Minor {1} Patch {2}" -f ( + $opensslVersion.Major, $opensslVersion.Minor, $opensslVersion.Build)) + + $openssl, $cryptoSource, $sslSource = switch ($opensslVersion) { + { $_.Major -eq 1 -and $_.Minor -eq 1 } { '1.1', 'libcrypto.1.1.dylib', 'libssl.1.1.dylib' } + { $_.Major -eq 3 } { '3', 'libcrypto.3.dylib', 'libssl.3.dylib' } + # Just default to 1.1 in case something catastrophic went wrong + default { '1.1', 'libcrypto.1.1.dylib', 'libssl.1.1.dylib' } + } + + [PSCustomObject]@{ + Distribution = $distribution + StandardLib = 'macOS' + OpenSSL = $openssl + LibCrypto = @{ + Source = $cryptoSource + Target = $libDetails.LibCrypto + } + LibSSL = @{ + Source = $sslSource + Target = $libDetails.LibSSL + } + } + } + } + default { + $opensslVersion = (Get-OpenSSLInfo).Version + Write-Verbose -Message ("OpenSSL Version: Major {0} Minor {1} Patch {2}" -f ( + $opensslVersion.Major, $opensslVersion.Minor, $opensslVersion.Build)) + + $openssl = switch ($opensslVersion) { + { $_.Major -eq 1 -and $_.Minor -eq 0 } { '1.0' } + { $_.Major -eq 1 -and $_.Minor -eq 1 } { '1.1' } + { $_.Major -eq 3 } { '3' } + } + + $cStd = $null + try { + [void][PSWSMan.Native]::gnu_get_libc_version() + $cStd = 'glibc' + } + catch [EntryPointNotFoundException] { + # gnu_get_libc_version() is GLIBC, we fallback on a check to musl through ldd --version. + $libcInfo = exec ldd --version + $libcVerbose = "Not glibc, checking musl with ldd --version:`nSTDOUT: {0}`nSTDERR: {1}`nRC: {2}" -f ( + $libcInfo.Stdout, $libcInfo.Stderr, $libcInfo.ExitCode) + Write-Verbose -Message $libcVerbose + + # ldd --version can output on either STDOUT/STDERR so we check both + if (($libcInfo.Stdout + $libcInfo.Stderr).Contains('musl', 'CurrentCultureIgnoreCase')) { + $cStd = 'musl' + } + } + + # We don't need to modify the symlinks as the linked SSL libs should already match what's in the PATH. + # Only exception is CentOS 7 which has libcrypto.so.10 and libssl.so.10. + # | OpenSSL Version | crypto name | ssl name | + # | 1.0.x | libcrypto.so.1.0.0 | libssl.so.1.0.0 | + # | 1.1.x | libcrypto.so.1.1 | libssl.so.1.1 | + # | 3.x | libcrypto.so.3 | libssl.so.3 | + if ($distribution -eq 'centos7') { + $libCrypto = @{ + Source = 'libcrypto.so.1.0.0' + Target = '/lib64/libcrypto.so.10' + } + $libSSL = @{ + Source = 'libssl.so.1.0.0' + Target = '/lib64/libssl.so.10' + } + } + else { + $libCrypto = $null + $libSSL = $null + } + + [PSCustomObject]@{ + Distribution = $distribution + StandardLib = $cStd + OpenSSL = $openssl + LibCrypto = $libCrypto + LibSSL = $libSSL + } + } + } +} + Function Get-Distribution { <# .SYNOPSIS @@ -170,25 +551,6 @@ Function Get-Distribution { $distribution } -Function Get-ValidDistributions { - <# - .SYNOPSIS - Outputs a list of valid distributions available to PSWSMan - #> - [CmdletBinding()] - param () - - - Get-ChildItem -LiteralPath $Script:LibPath -Directory | ForEach-Object -Process { - $libExtension = if ($_.Name -eq 'macOS') { 'dylib' } else { 'so' } - - $libraries = Get-ChildItem -LiteralPath $_.FullName -File -Filter "*.$libExtension" - if ($libraries) { - $_.name - } - } -} - Function Disable-WSManCertVerification { <# .SYNOPSIS @@ -255,7 +617,7 @@ Function Enable-WSManCertVerification { .DESCRIPTION Enables certificate verification for any WSMan requests globally. This can be enabled for just the CA or CN checks - or for all checks. The absence of a switch does not disable those checks, it only enables the specific check + or for all checks. The absence of a switch does not disable those checksomi, it only enables the specific check requested if it was not enabled already. .PARAMETER CACheck @@ -370,7 +732,7 @@ Function Install-WSMan { Install the patched WSMan libs for the current distribution. .PARAMETER Distribution - Specify the distribution to install the libraries for. If not set then the current distribution will calculated. + Deprecated and no longer used. .EXAMPLE # Need to run as root @@ -386,27 +748,24 @@ Function Install-WSMan { $Distribution ) - if (-not $Distribution) { - $Distribution = Get-Distribution - - if (-not $Distribution) { - Write-Error -Message "Failed to find distribution for current host" -Category InvalidOperation - return - } + if ($Distribution) { + Write-Warning -Message "-Distribution is deprecated and will be removed in a future version" } - Write-Verbose -Message "Installing WSMan libs for '$Distribution'" - $validDistributions = Get-ValidDistributions - if ($Distribution -notin $validDistributions) { - $distroList = "'$($validDistributions -join "', '")'" - $msg = "Unsupported distribution '$Distribution'. Supported distributions: $distroList" - Write-Error -Message $msg -Category InvalidArgument + $hostInfo = Get-HostInfo + + if (-not $hostInfo.StandardLib -or -not $hostInfo.OpenSSL) { + $msg = "Failed to select the necessary library, the host isn't macOS, Linux based on GLIBC or musl, or OpenSSL isn't installed" + Write-Error -Message $msg -Category InvalidOperation return } + $library = '{0}-{1}' -f ($hostInfo.StandardLib, $hostInfo.OpenSSL) + Write-Verbose -Message "Installing WSMan libs for '$library'" + $pwshDir = Split-Path -Path ([PSObject].Assembly.Location) -Parent - $distributionLib = Join-Path $Script:LibPath -ChildPath $Distribution - $libExtension = if ($distribution -eq 'macOS') { 'dylib' } else { 'so' } + $distributionLib = Join-Path $Script:LibPath -ChildPath $library + $libExtension = if ($hostInfo.StandardLib -eq 'macOS') { 'dylib' } else { 'so' } $notify = $false Get-ChildItem -LiteralPath $distributionLib -File -Filter "*.$libExtension" | ForEach-Object -Process { @@ -434,12 +793,42 @@ Function Install-WSMan { } } + # These symlinks are either no longer needed or we set them to our own path. + Get-Item -Path (Join-Path -Path $pwshDir -ChildPath 'lib*.so*') | + Where-Object { $_.Name -match 'lib(ssl|crypto)\.so.*' } | + ForEach-Object -Process { + Write-Verbose -Message "Removing existing symlink '$($_.FullName)'" + $_ | Remove-Item -Force + } + + $hostInfo.LibCrypto, $hostInfo.LibSSL | ForEach-Object -Process { + if (-not $_) { + return + } + + $srcPath = Join-Path -Path $pwshDir -ChildPath $_.Source + $create = $true + $srcLink = Get-Item -LiteralPath $srcPath -ErrorAction SilentlyContinue + if ($srcLink) { + if ($srcLink.Target -ne $_.Target) { + $srcLink | Remove-Item -Force + } + else { + $create = $false + } + } + + if ($create) { + Write-Verbose -Message "Creating symbolic link '$srcPath' -> '$($_.Target)'" + New-Item -Path $srcPath -ItemType SymbolicLink -Value $_.Target | Out-Null + } + } + if ($notify) { $msg = 'WSMan libs have been installed, please restart your PowerShell session to enable it in PowerShell' Write-Warning -Message $msg } } -Register-ArgumentCompleter -CommandName Install-WSMan -ParameterName Distribution -ScriptBlock { Get-ValidDistributions } Function Register-TrustedCertificate { <# @@ -450,8 +839,8 @@ Function Register-TrustedCertificate { Registers a certificate, or a chain or certificates, into the trusted store for the current Linux distribution. .PARAMETER Name - The name of the certificate file to use when placing it into the trusted store directory. If not set then a random - filename with the prefix 'PSWSMan-' will be used. + The name of the certificate file to use when placing it into the trusted store directory. If not set then the + value 'PSWSMan-(sha256 hash of certs)' will be used. .PARAMETER Path Specifies the path of a certificate to register. Wildcard characters are permitted. @@ -528,37 +917,23 @@ Function Register-TrustedCertificate { '/etc/ca-certificates/trust-source/anchors', 'update-ca-trust extract' } macOS { - # macOS is special, we don't use the builtin LibreSSL setup and rely on brew to provide OpenSSL. This - # means the path to the cert dir could change at any point in the future and we can't rely on default - # system locations. Instead we use otool to figure out the linked location of openssl and use that. If - # that fails then fallback to what should be the default '/user/local/etc/openssl@1.1/certs'. - $libmiPath = Join-Path -Path $Script:Libpath -ChildPath 'macOS' -AdditionalChildPath 'libmi.dylib' - - $opensslPath = $null - if (Test-Path -LiteralPath $libmiPath) { - $opensslPath = exec otool -L $libmiPath -ErrorAction SilentlyContinue | - Select-String -Pattern '\s+(\/.*libssl\..*\.dylib)\s+\(.*\)' | - ForEach-Object -Process { Split-Path -Path (Split-Path -Path $_.Matches[0].Groups[1]) } | - Select-Object -First 1 - } - elseif (Get-Command -Name brew -CommandType Application -ErrorAction SilentlyContinue) { - $opensslPath = exec brew --prefix openssl -ErrorAction SilentlyContinue - } - - if ($opensslPath) { - $openssl = Join-Path $opensslPath -ChildPath bin -AdditionalChildPath openssl - $certDirectory = exec $openssl @('version', '-d') -ErrorAction SilentlyContinue | - Select-String -Pattern 'OPENSSLDIR:\s+[\"|''](.*)[\"|'']$' | - ForEach-Object -Process { $_.Matches[0].Groups[1].Value } | - Select-Object -First 1 - } - + # macOS is special, we don't use the builtin LibreSSL setup and rely on brew or port to provide + # OpenSSL. This means the path to the cert dir could change at any point in the future and we can't + # rely on default system locations. Instead we determine the path to the libssl.dylib library and use + # that to PInvoke the OPENSSLDIR value that it has registered. If that fails then fallback to what + # should be the brew default '/user/local/etc/openssl@1.1/certs'. + $libSSL = (Get-MacOSOpenSSL).LibSSL + + $opensslPath = Split-Path -Path (Split-Path $libSSL -Parent) -Parent + $opensslBin = Join-Path -Path $opensslPath -ChildPath bin + $cRehash = Join-Path -Path $opensslBin -ChildPath c_rehash + + $certDirectory = (Get-OpenSSLInfo -LibSSL $libSSL).SSLDir if (-not $certDirectory) { - $certDirectory = '/usr/local/etc/openssl@1.1/certs' + $certDirectory = '/usr/local/etc/openssl@1.1' } - $cRehash = Join-Path -Path $opensslPath -ChildPath bin -AdditionalChildPath c_rehash - $certDirectory, $cRehash + (Join-Path -Path $certDirectory -ChildPath certs), $cRehash } { $_ -like 'centos*' -or $_ -like 'fedora*' } { '/etc/pki/ca-trust/source/anchors', 'update-ca-trust extract' @@ -571,8 +946,10 @@ Function Register-TrustedCertificate { } Write-Verbose "Trust directory '$certPath' - Refresh command '$refreshCommand'" - if (-not (Test-Path -LiteralPath $certPath)) { - $msg = "Failed to find the expected cert trust path at '$certPath' for distribution '$distribution'" + # We create the child dir if it doesn't exist but we want the parent to at least exist + $parentDir = Split-Path $certPath -Parent + if (-not (Test-Path -LiteralPath $parentDir)) { + $msg = "Failed to find the expected cert trust parent dir at '$parentDir' for distribution '$distribution'" Write-Error -Message $msg -Category ObjectNotFound $failed = $true return @@ -664,7 +1041,15 @@ Function Register-TrustedCertificate { } if (-not $Name) { - $Name = "PSWSMan-$([IO.Path]::GetRandomFileName())" + $hashStr = (Get-FileHash -LiteralPath $tempFile -Algorithm SHA256).Hash + $Name = "PSWSMan-$hashStr" + } + + if (-not (Test-Path $certPath)) { + if ($PSCmdlet.ShouldProcess($certPath, 'Create')) { + Write-Verbose -Message "Creating trust cert dir at '$certPath'" + New-Item -Path $certPath -ItemType Directory | Out-Null + } } $destCertPath = Join-Path -Path $certPath -ChildPath "$Name.$certExtension" @@ -672,6 +1057,9 @@ Function Register-TrustedCertificate { Write-Verbose -Message "Creating trust cert file at '$destCertPath'" Copy-Item -LiteralPath $tempFile -Destination $destCertPath -Force + # The file must be executable + exec chmod 755 $destCertPath | Out-Null + # The command to run may contain argument, just use Invoke-Expression as the input is statically defined. Write-Verbose -Message "Refreshing the trusted certificate directory with '$refreshCommand'" Invoke-Expression -Command $refreshCommand diff --git a/Unix/base/GNUmakefile b/Unix/base/GNUmakefile index 6322713d1..e66871833 100644 --- a/Unix/base/GNUmakefile +++ b/Unix/base/GNUmakefile @@ -7,45 +7,47 @@ else LIBRARY = base endif +# JBOREAN CHANGE: We can cut down what is not needed for the WSMan client +# Removed: +# classdecl.c +# env.c +# fieldprint.c +# getopt.c +# indent.c +# instanceprint.c +# interaction.c +# messagesprint.c +# miextras.c +# multiplex.c +# parameters.c +# pidfile.c +# process.c +# ptrarray.c +# random.c +# stringarray.c SOURCES = \ base.c \ batch.c \ buf.c \ class.c \ - classdecl.c \ instance.c \ - instanceprint.c \ messages.c \ - messagesprint.c \ - interaction.c \ list.c \ - parameters.c \ result.c \ schemadecl.c \ - stringarray.c \ types.c \ packing.c \ helpers.c \ naming.c \ field.c \ - fieldprint.c \ - env.c \ - process.c \ - pidfile.c \ paths.c \ strand.c \ strarr.c \ user.c \ credcache.c \ conf.c \ - getopt.c \ base64.c \ - indent.c \ - miextras.c \ - multiplex.c \ - ptrarray.c \ timer.c \ - random.c \ $(TOP)/sock/sock.c \ $(TOP)/sock/addr.c \ $(TOP)/sock/selector.c diff --git a/Unix/base/user.c b/Unix/base/user.c index 97afc888c..19cf7ba62 100644 --- a/Unix/base/user.c +++ b/Unix/base/user.c @@ -20,11 +20,12 @@ # include # include # include -# if defined(CONFIG_OS_DARWIN) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1058 -# include -# else -# include -# endif +// JBOREAN CHANGE: Not needed for WSMan client and removes the number of deps present +//# if defined(CONFIG_OS_DARWIN) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ <= 1058 +//# include +//# else +//# include +//# endif # include # include # include @@ -49,21 +50,26 @@ static PermissionGroups *s_deniedList = NULL; const char* GetHomeDir() { + // JBOREAN CHANGE: Not needed for WSMan client. + return NULL; + + /* char* home = NULL; struct passwd *pwd = NULL; errno = 0; - /* getuid() is always successful */ + // getuid() is always successful pwd = getpwuid(getuid()); if (pwd == NULL) { return NULL; } - /* copy pw_dir since we do not own pwd */ + // copy pw_dir since we do not own pwd home = PAL_Strdup(pwd->pw_dir); return (const char*)home; + */ } @@ -71,6 +77,8 @@ static int GetGroupName( gid_t gid, char name[GROUPNAME_SIZE]); +// JBOREAN CHANGE: Not needed for WSMan Client +/* static int _authCallback( int numMessages, #if defined(CONFIG_OS_LINUX) || defined(CONFIG_OS_DARWIN) || defined(CONFIG_OS_BSD) @@ -84,14 +92,14 @@ static int _authCallback( const char* password = (const char*)applicationData; int i; - /* If zero (or megative) messages, return now */ + // If zero (or megative) messages, return now if (numMessages <= 0) { return PAM_CONV_ERR; } - /* Allocate the responses */ + // Allocate the responses *response = (struct pam_response*)SystemCalloc( numMessages, @@ -102,7 +110,7 @@ static int _authCallback( return PAM_BUF_ERR; } - /* Copy the password to the response messages */ + // Copy the password to the response messages for (i = 0; i < numMessages; i++) { @@ -120,11 +128,16 @@ static int _authCallback( return PAM_SUCCESS; } +*/ int PamCheckUser( const char* user, const char* password) { + // JBOREAN CHANGE: Not needed for WSMan client + return -1; + + /* struct pam_conv conv; pam_handle_t* t = 0; @@ -161,6 +174,7 @@ int PamCheckUser( pam_end(t,close_ret); return 0; + */ } static int _CreateChildProcess( diff --git a/Unix/build.mak b/Unix/build.mak index f7b6f956e..721ea9f49 100644 --- a/Unix/build.mak +++ b/Unix/build.mak @@ -62,9 +62,9 @@ DIRECTORIES += pal #DIRECTORIES += nits #DIRECTORIES += ut -ifeq ($(COMPILER),GNU) -DIRECTORIES += strhash -endif +#ifeq ($(COMPILER),GNU) +#DIRECTORIES += strhash +#endif #DIRECTORIES += mof DIRECTORIES += sock DIRECTORIES += base diff --git a/Unix/buildtool b/Unix/buildtool index c4e25e246..eecb06fb6 100755 --- a/Unix/buildtool +++ b/Unix/buildtool @@ -1238,29 +1238,38 @@ if [ "$arg1" = "syslibs" ]; then r="" case "$platform" in + # JBOREAN CHANGE: Don't need pam for WSMan client LINUX_IX86_GNU|LINUX_X86_64_GNU|LINUX_PPC_GNU|LINUX_ARM_GNU) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; MONTAVISTA_IX86_GNU) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; NETBSD_IX86_GNU) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; SUNOS_I86PC_SUNPRO|SUNOS_SPARC_SUNPRO) - r="-lpthread -lsocket -lnsl -ldl -lpam" + #r="-lpthread -lsocket -lnsl -ldl -lpam" + r="-lpthread -lsocket -lnsl -ldl" ;; AIX_PPC_IBM) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; HPUX_IA64_HP) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; HPUX_PARISC_HP) - r="-lpthread -lpam" + #r="-lpthread -lpam" + r="-lpthread" ;; DARWIN_IX86_GNU) - r="-lpthread -ldl -lpam" + #r="-lpthread -ldl -lpam" + r="-lpthread -ldl" ;; esac diff --git a/Unix/http/httpclientauth.c b/Unix/http/httpclientauth.c index 096b1ee16..ca6f18c73 100644 --- a/Unix/http/httpclientauth.c +++ b/Unix/http/httpclientauth.c @@ -903,8 +903,9 @@ static _Success_(return == 0) int _GssClientInitLibrary( _In_ void* data, _Outpt _g_gssClientState.krb5FreeCredContents = (krb5FreeCredContentsFn) fn_handle; #endif - return _ValidateClientCredentials(context) == 0; - //return TRUE; + // JBOREAN CHANGE: This just seems wrong and is just more things that can fail. + //return _ValidateClientCredentials(context) == 0; + return TRUE; } failed: diff --git a/Unix/midll/GNUmakefile b/Unix/midll/GNUmakefile index 8d0d9de37..e4d683606 100644 --- a/Unix/midll/GNUmakefile +++ b/Unix/midll/GNUmakefile @@ -9,8 +9,9 @@ ifeq ($(OS),DARWIN) GENERATE_ORIGIN=1 endif -# JBOREAN CHANGE: We only need release for PowerShell -DIRECTORIES = release +# JBOREAN CHANGE: We only need origin for PowerShell +# origin uses rpath = $ORIGIN allowing us to load libs in the same dir +DIRECTORIES = origin #ifeq ($(GENERATE_ORIGIN),1) # DIRECTORIES = release origin diff --git a/Unix/midll/origin/GNUmakefile b/Unix/midll/origin/GNUmakefile index 52256e189..d308fe1c0 100644 --- a/Unix/midll/origin/GNUmakefile +++ b/Unix/midll/origin/GNUmakefile @@ -1,7 +1,8 @@ TOP = ../.. include $(TOP)/config.mak -CSHLIBRARY = mi_origin +# JBOREAN CHANGE: We just want to simplify things and set this to mi to match release +CSHLIBRARY = mi SOURCES = \ ../gnumain.c diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 592b8d507..a90f25dec 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -10,6 +10,59 @@ trigger: stages: - stage: Build jobs: + + - job: Linux + pool: + vmImage: ubuntu-18.04 + strategy: + matrix: + glibc-1.0: + distribution: glibc-1.0 + glibc-1.1: + distribution: glibc-1.1 + glibc-3: + distribution: glibc-3 + musl-1.1: + distribution: musl-1.1 + musl-3: + distribution: musl-3 + + steps: + - script: ./build.py $(distribution) --docker + env: + OMI_BUILDVERSION_BUILDNR: $(Build.BuildId) + displayName: Build + + - task: PublishPipelineArtifact@1 + inputs: + targetPath: PSWSMan/lib/$(distribution)/ + artifactName: $(distribution) + displayName: Publish artifacts + + - job: macOS + pool: + vmImage: macOS-10.15 + strategy: + matrix: + macOS-1.1: + distribution: macOS-1.1 + macOS-3: + distribution: macOS-3 + + steps: + - script: ./build.py $(distribution) + env: + OMI_BUILDVERSION_BUILDNR: $(Build.BuildId) + displayName: Build + + - task: PublishPipelineArtifact@1 + inputs: + targetPath: PSWSMan/lib/$(distribution)/ + artifactName: $(distribution) + displayName: Publish artifacts + +- stage: Test + jobs: - job: Linux pool: @@ -20,14 +73,10 @@ stages: distribution: centos7 CentOS8: distribution: centos8 - Debian8: - distribution: debian8 Debian9: distribution: debian9 Debian10: distribution: debian10 - Fedora31: - distribution: fedora31 Fedora32: distribution: fedora32 Fedora33: @@ -44,10 +93,10 @@ stages: distribution: alpine3 steps: - - script: ./build.py $(distribution) --docker - env: - OMI_BUILDVERSION_BUILDNR: $(Build.BuildId) - displayName: Build + - task: DownloadPipelineArtifact@2 + inputs: + source: current + path: PSWSMan/lib - pwsh: | $version = (Import-Module -Name ./PSWSMan -PassThru).Version.ToString(3) + ".$(Build.BuildId)" @@ -57,36 +106,24 @@ stages: - script: ./test.py $(distribution) --docker --verify-version $(BuildVersion) displayName: Check compiled libraries are loadable and are set to the correct version - - task: PublishPipelineArtifact@1 - inputs: - targetPath: PSWSMan/lib/$(distribution)/ - artifactName: $(distribution) - displayName: Publish artifacts - - job: macOS pool: vmImage: macOS-10.15 steps: - - script: ./build.py macOS - env: - OMI_BUILDVERSION_BUILDNR: $(Build.BuildId) - displayName: Build + - task: DownloadPipelineArtifact@2 + inputs: + source: current + path: PSWSMan/lib - pwsh: | $version = (Import-Module -Name ./PSWSMan -PassThru).Version.ToString(3) + ".$(Build.BuildId)" Write-Host "##vso[task.setvariable variable=BuildVersion]${version}" displayName: Get module version - - script: ./test.py macOS --verify-version $(BuildVersion) + - script: ./test.py macOS-1.1 --verify-version $(BuildVersion) displayName: Check compiled libraries are loadable and are set to the correct version - - task: PublishPipelineArtifact@1 - inputs: - targetPath: PSWSMan/lib/macOS/ - artifactName: macOS - displayName: Publish artifacts - - stage: Publish jobs: - job: Publish diff --git a/build.py b/build.py index db5faeb54..7e3fe9a7b 100755 --- a/build.py +++ b/build.py @@ -29,6 +29,76 @@ ) +def compile_openssl(openssl_version, script_steps, configure_args, distribution): + build_path = '/tmp/openssl-%s-build' % openssl_version + + if distribution.startswith('macOS'): + compile_arg = 'MACOSX_DEPLOYMENT_TARGET=10.15 ./Configure darwin64-x86_64-cc shared' + else: + compile_arg = 'CFLAGS=-fPIC ./config shared' + + jobs = '' + if openssl_version.startswith('1.0'): + # OpenSSL 1.0.x is problematic with concurrently builds so set the max to just 1. + jobs = '1' + + compile_openssl = '''wget \ + -q -O '/tmp/openssl-{0}.tar.gz' \ + 'https://www.openssl.org/source/openssl-{0}.tar.gz' + +tar -xf '/tmp/openssl-{0}.tar.gz' -C /tmp +cd '/tmp/openssl-{0}' + +{1} \ + '--prefix={2}' +make -j{3} +make install_sw'''.format(openssl_version, compile_arg, build_path, jobs) + + script_steps.append(('Compiling OpenSSL %s' % openssl_version, compile_openssl)) + + # TODO: Enable this once AZP opens up the Big Sur agents so we can actually run this in CI. + if distribution.startswith('macOS') and False: + # We want to create a fat (x64 and arm) library so we can compile mi for arm. + compile_openssl = ''' +MACOSX_DEPLOYMENT_TARGET=10.15 ./Configure \ + darwin64-arm64-cc shared \ + '--prefix={0}-arm64' +make clean +make -j +make install_sw + +echo "Combining x86_64 and arm64 binaries" + +LIB_DIR='{0}' + +# Loops through all the .a and .dylibs in lib (that aren't symlinks) and combines them +for file in "${{LIB_DIR}}"/lib/lib*; do + if [ -f "${{file}}" ] && [ ! -L "${{file}}" ]; then + FILENAME="$( basename "${{file}}" )" + echo "Combining OpenSSL lib ${{file}}" + lipo -create "${{file}}" "${{LIB_DIR}}-arm64/lib/${{FILENAME}}" -output "${{file}}" + fi +done + +lipo -create \ + '{0}/bin/openssl' \ + '{0}-arm64/bin/openssl' \ + -output '{0}/bin/openssl' +'''.format(build_path) + script_steps.append(('Compiling OpenSSL for arm64', compile_openssl)) + + script_steps.append(('Finalise OpenSSL install', '''export OPENSSL_ROOT_DIR="{0}" +cd "${{OMI_REPO}}/Unix" +'''.format(build_path))) + + configure_args.extend([ + '--openssl="{0}/bin/openssl"'.format(build_path), + '--opensslcflags="-I{0}/include"'.format(build_path), + '--openssllibs="-L{0}/lib -lssl -lcrypto -lz"'.format(build_path), + '--openssllibdir="{0}/lib"'.format(build_path), + ]) + + def main(): """Main program body.""" args = parse_args() @@ -44,7 +114,7 @@ def main(): echo "Current Directory: $OMI_REPO" cd Unix''')] output_dirname = 'build-%s' % distribution - library_extension = 'dylib' if distribution == 'macOS' else 'so' + library_extension = 'dylib' if distribution.startswith('macOS') else 'so' if not args.skip_deps: dep_script = build_package_command(distro_details['package_manager'], distro_details['build_deps']) @@ -70,22 +140,29 @@ def main(): # macOS on Azure Pipelines has OpenSSL 1.0.2 installed but we want to compile against the OpenSSL version in our # dep list which is openssl@1.1. Because the deps are installed at runtime we need our build script to find that # value and add to our configure args. - if distribution == 'macOS': - script_steps.append(('Getting OpenSSL locations for macOS', - 'OPENSSL_PREFIX="$(brew --prefix openssl@1.1)"\necho "Using OpenSSL at \'${OPENSSL_PREFIX}\'"')) + if distribution.startswith('macOS'): + if distro_details['openssl_version']: + compile_openssl(distro_details['openssl_version'], script_steps, configure_args, distribution) - configure_args.extend([ - '--openssl="${OPENSSL_PREFIX}/bin/openssl"', - '--opensslcflags="-I${OPENSSL_PREFIX}/include"', - '--openssllibs="-L${OPENSSL_PREFIX}/lib -lssl -lcrypto -lz"', - '--openssllibdir="${OPENSSL_PREFIX}/lib"', - ]) + else: + script_steps.append(('Getting OpenSSL locations for macOS', + 'OPENSSL_PREFIX="$(brew --prefix openssl@1.1)"\necho "Using OpenSSL at \'${OPENSSL_PREFIX}\'"')) + + configure_args.extend([ + '--openssl="${OPENSSL_PREFIX}/bin/openssl"', + '--opensslcflags="-I${OPENSSL_PREFIX}/include"', + '--openssllibs="-L${OPENSSL_PREFIX}/lib -lssl -lcrypto -lz"', + '--openssllibdir="${OPENSSL_PREFIX}/lib"', + ]) + + elif distro_details['openssl_version']: + compile_openssl(distro_details['openssl_version'], script_steps, configure_args, distribution) configure_script = '''echo -e "Running configure with:\\n\\t{0}" {1}'''.format('\\n\\t'.join(configure_args), build_multiline_command('./configure', configure_args)) script_steps.append(('Running configure', configure_script)) - script_steps.append(('Running make', 'make')) + script_steps.append(('Running make', 'make -j')) script_steps.append(('Copying libmi to pwsh build dir', '''if [ -d '../PSWSMan/lib/{0}' ]; then echo "Clearing existing build folder at 'PSWSMan/lib/{0}'" @@ -128,13 +205,51 @@ def main(): make psrpclient cp libpsrpclient.* "${{OMI_REPO}}/PSWSMan/lib/{2}/"'''.format(output_dirname, built_type, distribution))) - if distribution == 'macOS': + if distribution.startswith('macOS'): script_steps.append(('Patch libmi dylib path for libpsrpclient', - '''echo "Patching '${{OMI_REPO}}/PSWSMan/lib/{1}/libpsrpclient.dylib' libmi location" + '''echo "Patching '${{OMI_REPO}}/PSWSMan/lib/{0}/libpsrpclient.dylib' libmi location" install_name_tool -change \\ - '{0}/lib/libmi.dylib' \\ - '@executable_path/libmi.dylib' \\ - "${{OMI_REPO}}/PSWSMan/lib/{1}/libpsrpclient.dylib"'''.format(args.prefix, distribution))) + '@rpath/libmi.dylib' \\ + '@loader_path/libmi.dylib' \\ + "${{OMI_REPO}}/PSWSMan/lib/{0}/libpsrpclient.dylib"'''.format(distribution))) + + if distro_details['openssl_version']: + openssl_version = distro_details['openssl_version'] + + script_steps.append(('Patch OpenSSL dylib path for libmi', + '''echo "Patching '${{OMI_REPO}}/PSWSMan/lib/{1}/libmi.dylib' SSL locations" + +LIB_DIR='/tmp/openssl-{0}-build' + +# Loops through all the .dylibs in lib (that aren't symlinks) and uses that as the path to change +for file in "${{LIB_DIR}}"/lib/lib*.dylib; do + if [ -f "${{file}}" ] && [ ! -L "${{file}}" ]; then + FILENAME="$( basename "${{file}}" )" + echo "Setting relative link path for ${{FILENAME}}" + + install_name_tool -change \\ + "${{file}}" \\ + "@loader_path/${{FILENAME}}" \\ + "${{OMI_REPO}}/PSWSMan/lib/{1}/libmi.dylib" + fi +done'''.format(openssl_version, distribution))) + + script_steps.append(('Output linked information', + '''echo "libpsrpclient links" +otool -L "${{OMI_REPO}}/PSWSMan/lib/{0}/libpsrpclient.dylib" + +echo "libmi links" +otool -L "${{OMI_REPO}}/PSWSMan/lib/{0}/libmi.dylib" +'''.format(distribution))) + + else: + script_steps.append(('Output linked information', + '''echo "libpsrpclient links" +ldd "${{OMI_REPO}}/PSWSMan/lib/{0}/libpsrpclient.so" || true + +echo "libmi links" +ldd "${{OMI_REPO}}/PSWSMan/lib/{0}/libmi.so" || true +'''.format(distribution))) build_script = build_bash_script(script_steps) diff --git a/distribution_meta/alpine3.json b/distribution_meta/alpine3.json index 21634d0d0..05cb2fcd2 100644 --- a/distribution_meta/alpine3.json +++ b/distribution_meta/alpine3.json @@ -8,7 +8,6 @@ "cmake", "git", "krb5-dev", - "linux-pam-dev", "make", "openssl", "openssl-dev", @@ -29,6 +28,7 @@ "libtool", "libunistring-dev", "make", + "openssl", "openssl-dev", "samba-dev", "zlib-dev" diff --git a/distribution_meta/archlinux.json b/distribution_meta/archlinux.json index 51b0c62c9..d92f9fa6c 100644 --- a/distribution_meta/archlinux.json +++ b/distribution_meta/archlinux.json @@ -9,7 +9,6 @@ "glibc", "inetutils", "krb5", - "lsb-release", "make", "openssl", "pkgconf", @@ -23,6 +22,7 @@ "doxygen", "krb5", "libwbclient", + "openssl", "which" ], "cert_staging_dir": "/etc/ca-certificates/trust-source/anchors", diff --git a/distribution_meta/centos7.json b/distribution_meta/centos7.json index 69783e798..8703f45eb 100644 --- a/distribution_meta/centos7.json +++ b/distribution_meta/centos7.json @@ -3,25 +3,20 @@ "package_manager": "yum", "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", "build_deps": [ - "bind-utils", "cmake", "gcc", - "gcc-c++", "git", "krb5-devel", "make", "openssl", "openssl-devel", - "pam-devel", - "redhat-lsb-core", - "rpm-build", - "rpm-devel", "which" ], "test_deps": [ "gssntlmssp", "krb5-devel", "krb5-workstation", + "openssl", "powershell", "which" ], diff --git a/distribution_meta/centos8.json b/distribution_meta/centos8.json index 58fa5d210..219505416 100644 --- a/distribution_meta/centos8.json +++ b/distribution_meta/centos8.json @@ -3,25 +3,20 @@ "package_manager": "yum", "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", "build_deps": [ - "bind-utils", "cmake", "gcc", - "gcc-c++", "git", "krb5-devel", "make", "openssl", "openssl-devel", - "pam-devel", - "redhat-lsb-core", - "rpm-build", - "rpm-devel", "which" ], "test_deps": [ "gssntlmssp", "krb5-devel", "krb5-workstation", + "openssl", "powershell", "which" ], diff --git a/distribution_meta/debian10.json b/distribution_meta/debian10.json index 83040eee1..403767ab5 100644 --- a/distribution_meta/debian10.json +++ b/distribution_meta/debian10.json @@ -4,12 +4,9 @@ "microsoft_repo": "https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb", "build_deps": [ "cmake", - "g++", "git", "libkrb5-dev", - "libpam-dev", "libssl-dev", - "lsb-release", "make", "openssl", "pkg-config" @@ -19,6 +16,7 @@ "gss-ntlmssp", "krb5-user", "libkrb5-dev", + "openssl", "powershell" ], "cert_staging_dir": "/usr/local/share/ca-certificates", diff --git a/distribution_meta/debian8.json b/distribution_meta/debian8.json deleted file mode 100644 index 0330b408f..000000000 --- a/distribution_meta/debian8.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "container_image": "debian:8", - "package_manager": "apt", - "microsoft_repo": "https://packages.microsoft.com/config/debian/8/multiarch/packages-microsoft-prod.deb", - "build_deps": [ - "cmake", - "g++", - "git", - "libkrb5-dev", - "libpam-dev", - "libssl-dev", - "lsb-release", - "make", - "openssl", - "pkg-config" - ], - "test_deps": [ - "krb5-user", - "libkrb5-dev", - "powershell" - ], - "cert_staging_dir": "/usr/local/share/ca-certificates", - "cert_staging_cmd": "update-ca-certificates", - "cert_extension": "crt" -} diff --git a/distribution_meta/debian9.json b/distribution_meta/debian9.json index bef6f979a..06257a82a 100644 --- a/distribution_meta/debian9.json +++ b/distribution_meta/debian9.json @@ -4,12 +4,9 @@ "microsoft_repo": "https://packages.microsoft.com/config/debian/9/multiarch/packages-microsoft-prod.deb", "build_deps": [ "cmake", - "g++", "git", "libkrb5-dev", - "libpam-dev", "libssl-dev", - "lsb-release", "make", "openssl", "pkg-config" @@ -18,6 +15,7 @@ "gss-ntlmssp", "krb5-user", "libkrb5-dev", + "openssl", "powershell" ], "cert_staging_dir": "/usr/local/share/ca-certificates", diff --git a/distribution_meta/fedora32.json b/distribution_meta/fedora32.json index 18479196f..1ed1a82fd 100644 --- a/distribution_meta/fedora32.json +++ b/distribution_meta/fedora32.json @@ -4,24 +4,19 @@ "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", "build_deps": [ "cmake", - "bind-utils", "gcc", - "gcc-c++", "git", "krb5-devel", "make", "openssl", "openssl-devel", - "pam-devel", - "redhat-lsb-core", - "rpm-build", - "rpm-devel", "which" ], "test_deps": [ "gssntlmssp", "krb5-devel", "krb5-workstation", + "openssl", "powershell", "which" ], diff --git a/distribution_meta/fedora33.json b/distribution_meta/fedora33.json index 3d964e6a6..17e2fae57 100644 --- a/distribution_meta/fedora33.json +++ b/distribution_meta/fedora33.json @@ -4,24 +4,19 @@ "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", "build_deps": [ "cmake", - "bind-utils", "gcc", - "gcc-c++", "git", "krb5-devel", "make", "openssl", "openssl-devel", - "pam-devel", - "redhat-lsb-core", - "rpm-build", - "rpm-devel", "which" ], "test_deps": [ "gssntlmssp", "krb5-devel", "krb5-workstation", + "openssl", "powershell", "which" ], diff --git a/distribution_meta/fedora31.json b/distribution_meta/glibc-1.0.json similarity index 63% rename from distribution_meta/fedora31.json rename to distribution_meta/glibc-1.0.json index a5db82cc8..41a8fca73 100644 --- a/distribution_meta/fedora31.json +++ b/distribution_meta/glibc-1.0.json @@ -1,22 +1,17 @@ { - "container_image": "fedora:31", - "package_manager": "dnf", + "container_image": "centos:7", + "package_manager": "yum", "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", + "openssl_version": "1.0.2u", "build_deps": [ "cmake", - "bind-utils", "gcc", - "gcc-c++", "git", "krb5-devel", "make", - "openssl", - "openssl-devel", - "pam-devel", - "redhat-lsb-core", - "rpm-build", - "rpm-devel", - "which" + "wget", + "which", + "zlib-devel" ], "test_deps": [ "gssntlmssp", diff --git a/distribution_meta/glibc-1.1.json b/distribution_meta/glibc-1.1.json new file mode 100644 index 000000000..b43650fdd --- /dev/null +++ b/distribution_meta/glibc-1.1.json @@ -0,0 +1,25 @@ +{ + "container_image": "centos:7", + "package_manager": "yum", + "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", + "openssl_version": "1.1.1k", + "build_deps": [ + "cmake", + "gcc", + "git", + "krb5-devel", + "make", + "wget", + "which", + "zlib-devel" + ], + "test_deps": [ + "gssntlmssp", + "krb5-devel", + "krb5-workstation", + "powershell", + "which" + ], + "cert_staging_dir": "/etc/pki/ca-trust/source/anchors", + "cert_staging_cmd": "update-ca-trust extract" +} diff --git a/distribution_meta/glibc-3.json b/distribution_meta/glibc-3.json new file mode 100644 index 000000000..11d7ca883 --- /dev/null +++ b/distribution_meta/glibc-3.json @@ -0,0 +1,27 @@ +{ + "container_image": "centos:7", + "package_manager": "yum", + "microsoft_repo": "https://packages.microsoft.com/config/rhel/7/prod.repo", + "openssl_version": "3.0.0-alpha13", + "build_deps": [ + "cmake", + "gcc", + "git", + "krb5-devel", + "make", + "perl-Data-Dumper", + "perl-IPC-Cmd", + "wget", + "which", + "zlib-devel" + ], + "test_deps": [ + "gssntlmssp", + "krb5-devel", + "krb5-workstation", + "powershell", + "which" + ], + "cert_staging_dir": "/etc/pki/ca-trust/source/anchors", + "cert_staging_cmd": "update-ca-trust extract" +} diff --git a/distribution_meta/macOS.json b/distribution_meta/macOS-1.1.json similarity index 91% rename from distribution_meta/macOS.json rename to distribution_meta/macOS-1.1.json index 0991aabb8..cc93dc07f 100644 --- a/distribution_meta/macOS.json +++ b/distribution_meta/macOS-1.1.json @@ -2,9 +2,9 @@ "container_image": "", "package_manager": "brew", "microsoft_repo": "", + "openssl_version": "1.1.1k", "build_deps": [ "cmake", - "openssl@1.1", "pkg-config" ], "test_deps": [ diff --git a/distribution_meta/macOS-3.json b/distribution_meta/macOS-3.json new file mode 100644 index 000000000..b7356fce7 --- /dev/null +++ b/distribution_meta/macOS-3.json @@ -0,0 +1,16 @@ +{ + "container_image": "", + "package_manager": "brew", + "microsoft_repo": "", + "openssl_version": "3.0.0-alpha13", + "build_deps": [ + "cmake", + "pkg-config" + ], + "test_deps": [ + "openssl", + "cask:powershell" + ], + "cert_staging_dir": "/usr/local/etc/openssl@1.1/certs", + "cert_staging_cmd": "/usr/local/opt/openssl@1.1/bin/c_rehash" +} diff --git a/distribution_meta/musl-1.1.json b/distribution_meta/musl-1.1.json new file mode 100644 index 000000000..359286ae1 --- /dev/null +++ b/distribution_meta/musl-1.1.json @@ -0,0 +1,40 @@ +{ + "container_image": "alpine:3", + "package_manager": "apk", + "microsoft_repo": "", + "openssl_version": "1.1.1k", + "shell": "/bin/sh", + "build_deps": [ + "build-base", + "cmake", + "git", + "krb5-dev", + "linux-headers", + "make", + "perl", + "pkgconf", + "zlib-dev" + ], + "test_deps": [ + "source:gss-ntlmssp", + "source:powershell", + "ca-certificates", + "autoconf", + "automake", + "build-base", + "curl", + "git", + "icu-libs", + "krb5", + "krb5-dev", + "libtool", + "libunistring-dev", + "make", + "openssl-dev", + "samba-dev", + "zlib-dev" + ], + "cert_staging_dir": "/usr/local/share/ca-certificates", + "cert_staging_cmd": "update-ca-certificates", + "cert_extension": "crt" +} diff --git a/distribution_meta/musl-3.json b/distribution_meta/musl-3.json new file mode 100644 index 000000000..df643398d --- /dev/null +++ b/distribution_meta/musl-3.json @@ -0,0 +1,40 @@ +{ + "container_image": "alpine:3", + "package_manager": "apk", + "microsoft_repo": "", + "openssl_version": "3.0.0-alpha13", + "shell": "/bin/sh", + "build_deps": [ + "build-base", + "cmake", + "git", + "krb5-dev", + "linux-headers", + "make", + "perl", + "pkgconf", + "zlib-dev" + ], + "test_deps": [ + "source:gss-ntlmssp", + "source:powershell", + "ca-certificates", + "autoconf", + "automake", + "build-base", + "curl", + "git", + "icu-libs", + "krb5", + "krb5-dev", + "libtool", + "libunistring-dev", + "make", + "openssl-dev", + "samba-dev", + "zlib-dev" + ], + "cert_staging_dir": "/usr/local/share/ca-certificates", + "cert_staging_cmd": "update-ca-certificates", + "cert_extension": "crt" +} diff --git a/distribution_meta/ubuntu16.04.json b/distribution_meta/ubuntu16.04.json index 43b60358a..971962d38 100644 --- a/distribution_meta/ubuntu16.04.json +++ b/distribution_meta/ubuntu16.04.json @@ -4,12 +4,9 @@ "microsoft_repo": "https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb", "build_deps": [ "cmake", - "g++", "git", "libkrb5-dev", - "libpam-dev", "libssl-dev", - "lsb-release", "make", "openssl", "pkg-config" @@ -18,6 +15,7 @@ "gss-ntlmssp", "krb5-user", "libkrb5-dev", + "openssl", "powershell" ], "cert_staging_dir": "/usr/local/share/ca-certificates", diff --git a/distribution_meta/ubuntu18.04.json b/distribution_meta/ubuntu18.04.json index 674826206..2cf66bd15 100644 --- a/distribution_meta/ubuntu18.04.json +++ b/distribution_meta/ubuntu18.04.json @@ -4,12 +4,9 @@ "microsoft_repo": "https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb", "build_deps": [ "cmake", - "g++", "git", "libkrb5-dev", - "libpam-dev", "libssl-dev", - "lsb-release", "make", "openssl", "pkg-config" @@ -19,6 +16,7 @@ "gss-ntlmssp", "krb5-user", "libkrb5-dev", + "openssl", "powershell" ], "cert_staging_dir": "/usr/local/share/ca-certificates", diff --git a/distribution_meta/ubuntu20.04.json b/distribution_meta/ubuntu20.04.json index e62a60c48..88f952b69 100644 --- a/distribution_meta/ubuntu20.04.json +++ b/distribution_meta/ubuntu20.04.json @@ -4,12 +4,9 @@ "microsoft_repo": "https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb", "build_deps": [ "cmake", - "g++", "git", "libkrb5-dev", - "libpam-dev", "libssl-dev", - "lsb-release", "make", "openssl", "pkg-config" @@ -19,6 +16,7 @@ "gss-ntlmssp", "krb5-user", "libkrb5-dev", + "openssl", "powershell" ], "cert_staging_dir": "/usr/local/share/ca-certificates", diff --git a/docs/build.md b/docs/build.md index 855e13542..d5d5e77d8 100644 --- a/docs/build.md +++ b/docs/build.md @@ -29,24 +29,38 @@ There are some other arguments you can supply to alter the behaviour of the buil Once the build step is completed it will generate the compiled libraries at `PSWSMan/lib/{distribution}/*`. -The aim is to support the same distributions that PowerShell supports but that is a work in progress. -The distributions that are currently setup in the `build.py` script are: +The aim is to support the same distributions that PowerShell supports through universal builds that work across a wide range of distributions. +There are currently the following universal builds that are distributed with `PSWSMan`: + ++ [glibc-1.0.json](../distribution_meta/glibc-1.0.json) ++ [glibc-1.1.json](../distribution_meta/glibc-1.1.json) ++ [glibc-3.json](../distribution_meta/glibc-3.json) ++ [musl-1.1.json](../distribution_meta/musl-1.1.json) ++ [musl-3.json](../distribution_meta/musl-3.json) ++ [macOS-1.1.json](../distribution_meta/macOS-1.1.json) ++ [macOS-3.json](../distribution_meta/macOS-3.json) + +The `glibc` builds are designed for Linux distributions that run on GNU/Linux; CentOS, Ubuntu, Debian, Fedora, RHEL, OpenSUSE, etc. +The `musl` builds are designed for Linux distributions based on Busybox like Alpine. +The `macOS` build cannot be run on Docker but are designed for macOS. +Each build contains a number that relates to the OpenSSL version it is compiled against. +This is important as OpenSSL is not API/ABI compatible across these versions so we need to produce a separate library for each. + +There are also the following distribution specific setups that is used for testing these universal builds such as: + [alpine3.json](../distribution_meta/alpine3.json) + [archlinux.json](../distribution_meta/archlinux.json) + [centos7.json](../distribution_meta/centos7.json) + [centos8.json](../distribution_meta/centos8.json) -+ [debian8.json](../distribution_meta/debian8.json) + [debian9.json](../distribution_meta/debian9.json) + [debian10.json](../distribution_meta/debian10.json) -+ [fedora31.json](../distribution_meta/fedora31.json) + [fedora32.json](../distribution_meta/fedora32.json) -+ [macOS.json](../distribution_meta/macOS.json) - Cannot be built on a Docker container, must be built on an actual macOS host ++ [fedora33.json](../distribution_meta/fedora33.json) + [ubuntu16.04.json](../distribution_meta/ubuntu16.04.json) + [ubuntu18.04.json](../distribution_meta/ubuntu18.04.json) + [ubuntu20.04.json](../distribution_meta/ubuntu20.04.json) -The json file contains all the information required for `build.py` to install the depedencies and build the libraries. +These can also be used to build `libmi` specifically for that distribution if need be. ## Manually building diff --git a/docs/https_validation.md b/docs/https_validation.md index 7f6ae88ca..e567b62ec 100644 --- a/docs/https_validation.md +++ b/docs/https_validation.md @@ -159,7 +159,8 @@ If you don't wish to add the CA chain to the system wide trust store you should ### macOS Cert validation on macOS has it's own quirks that set it apart from Linux. -The OMI library is linked against OpenSSL that is installed from `brew` and not the TLS library that comes builtin to macOS. +The OMI library is typically linked against OpenSSL that is installed from `brew` and not the TLS library that comes builtin to macOS. +Since `PSWSMan>=2.2.0` it could now be linked to the `port` installed OpenSSL if `brew` is either not installed or has not installed the `openssl` package. When you install `openssl` with `brew`, the install process will take a copy of the existing system keychain and place it into a directory it itself uses. Any libraries that are linked to this OpenSSL install will use that directory and not the system keychain. Ultimately this means that it will trust any CAs that were present in the macOS keychain when OpenSSL was installed but if you wish to add any more CAs you need to add it yourself. diff --git a/integration_environment/test.yml b/integration_environment/test.yml index 96886c36f..668f83bab 100644 --- a/integration_environment/test.yml +++ b/integration_environment/test.yml @@ -28,7 +28,10 @@ (item.path | basename | splitext)[0] ] }} - when: (item.path | basename | splitext)[0] != 'macOS' + when: + - not (item.path | basename | splitext)[0].startswith('macOS') + - not (item.path | basename | splitext)[0].startswith('glibc') + - not (item.path | basename | splitext)[0].startswith('musl') loop: '{{ distribution_raw.files }}' - name: get a list of the final distributions to run diff --git a/libmi.tests.ps1 b/libmi.tests.ps1 index 378e322cd..1bdf4fa17 100755 --- a/libmi.tests.ps1 +++ b/libmi.tests.ps1 @@ -62,7 +62,7 @@ BeforeAll { } # Heimdal (used by macOS) requires this argument to successfully send the password to kinit - if ($Global:Distribution -eq 'macOS') { + if ($Global:Distribution.StartsWith('macOS')) { $kinitArgs.Add('--password-file=STDIN') } @@ -118,19 +118,25 @@ BeforeAll { Describe "PSWSMan tests" { It "Calculates the right distribution" { + $expected = $Global:Distribution + if ($expected.StartsWith('macOS')) { + $expected = 'macOS' + } + $actual = &(Get-Module PSWSMan) { Get-Distribution } - $actual | Should -Be $Global:Distribution + $actual | Should -Be $expected } - It "Doesn't error when installing libs again" { + # We need to run as root for macOS as it creates symlinks which just makes the tests harder to run so skip that. + It "Doesn't error when installing libs again" -Skip:($Global:Distribution.StartsWith('macOS')) { Install-WSMan -WarningVariable wv [bool]$wv | Should -Be $false } - It "Errors with invalid distribution" { - Install-WSMan -Distribution invalid -ErrorVariable ev -ErrorAction SilentlyContinue - $ev.Count | Should -Be 1 - $ev[0].Exception.Message | Should -BeLike "Unsupported distribution 'invalid'. Supported distributions: *" + It "Dep warning with -Distribution" -Skip:($Global:Distribution.StartsWith('macOS')) { + Install-WSMan -Distribution invalid -WarningVariable wv -WarningAction SilentlyContinue + $wv.Count | Should -Be 1 + $wv[0].Message | Should -Be "-Distribution is deprecated and will be removed in a future version" } # Alpine3 doesn't come with a copy of libmi or libpsrpclient so this test will fail when running there. @@ -139,7 +145,7 @@ Describe "PSWSMan tests" { @{ Name = 'libpsrpclient' } ) { $pwshDir = Split-Path -Path ([PSObject].Assembly.Location) -Parent - $libExtension = if ($Global:Distribution -eq 'macOS') { 'dylib' } else { 'so' } + $libExtension = if ($Global:Distribution.StartsWith('macOS')) { 'dylib' } else { 'so' } $libName = "$($Name).$($libExtension).bak" Test-Path -LiteralPath (Join-Path -Path $pwshDir -ChildPath $libName) -PathType Leaf | Should -Be $true @@ -191,9 +197,8 @@ Describe "PSRemoting through WSMan" { } # CentOS 7 does not have a new enough version of GSSAPI to work with NTLM auth. - # Debian 8 does not have the gss-ntlmssp package available. # macOS has troubles with NTLM over SPNEGO when it comes to message encryption. - It "Connects over HTTP with NTLM auth" -Skip:($Global:Distribution -in @('centos7', 'debian8', 'macOS')) { + It "Connects over HTTP with NTLM auth" -Skip:($Global:Distribution -in @('centos7') -or $Global:Distribution.StartsWith('macOS')) { $invokeParams = @{ ComputerName = $Global:TestHostInfo.HostnameIP Credential = $Global:TestHostInfo.Credential @@ -247,7 +252,7 @@ Describe "PSRemoting over HTTPS" { } | Select-Object -Property Name, Port # Older OpenSSL versions don't seem to report a verification error but a more generic one - if ($Global:Distribution -in @('debian8', 'ubuntu16.04', 'centos7')) { + if ($Global:Distribution -in @('ubuntu16.04', 'centos7')) { $Global:ExpectedVerificationError = '*error:14090086:SSL routines:func(144):reason(134)*' } else { $Global:ExpectedVerificationError = '*certificate verify failed*' @@ -279,15 +284,21 @@ Describe "PSRemoting over HTTPS" { [PSWSMan.Native]::unsetenv('SSL_CERT_FILE') } - # ChannelBindingToken doesn't work on SPNEGO with MIT krb5 until after 1.19. Fedora seems to have backported + # ChannelBindingToken doesn't work on SPNEGO with MIT krb5 until after 1.19. Fedora/CentOS 8 seems to have backported # further changes into the package which reports the older versions in reality has the fix so we also check that. # macOS uses Heimdal which isn't affected by that bug. - It "Connects over HTTPS - Negotiate" -Skip:($Global:Distribution -notin @('fedora32', 'fedora33', 'macOS') -and $Global:KrbVersion -lt [Version]'1.19') { + It "Connects over HTTPS - Negotiate" -Skip:( + (-not $Global:Distribution.StartsWith('fedora') -and -not $Global:Distribution.StartsWith('macOS') -and $Global:Distribution -ne 'centos8') -and + $Global:KrbVersion -lt [Version]'1.19' + ) { $actual = Invoke-Command @CommonInvokeParams -Port $GoodCertPort $actual | Should -Be $Global:TestHostInfo.NetbiosName } - It "Connects over HTTPS with NTLM auth" -Skip:($Global:Distribution -notin @('fedora32') -and $Global:KrbVersion -lt [Version]'1.19') { + It "Connects over HTTPS with NTLM auth" -Skip:( + (-not $Global:Distribution.StartsWith('fedora') -and $Global:Distribution -ne 'centos8') -and + $Global:KrbVersion -lt [Version]'1.19' + ) { # Using an IP address means we break Kerberos auth and fallback to NTLM $invokeParams = $CommonInvokeParams.Clone() $invokeParams.ComputerName = $Global:TestHostInfo.HostnameIP @@ -322,9 +333,7 @@ Describe "PSRemoting over HTTPS" { $actual | Should -Be $Global:TestHostInfo.NetbiosName } - # Debian 8 ships with a really old version of OpenSSL that does not offer CN verification. - $skipCN = 'debian8' -eq $Global:Distribution - It "Fails to verify the CN - " -Skip:$skipCN -TestCases @( + It "Fails to verify the CN - " -TestCases @( @{ Scenario = 'Default' Process = {} @@ -340,7 +349,7 @@ Describe "PSRemoting over HTTPS" { { Invoke-Command @CommonInvokeParams -Port $BadCNPort -Authentication Kerberos } | Should -Throw $Expected } - It "Ignores a CN failure with env value" -Skip:$skipCN { + It "Ignores a CN failure with env value" { Disable-WSManCertVerification -CNCheck $actual = Invoke-Command @CommonInvokeParams -Port $BadCNPort -Authentication Kerberos $actual | Should -Be $Global:TestHostInfo.NetbiosName @@ -366,7 +375,7 @@ Describe "PSRemoting over HTTPS" { $actual | Should -Be $Global:TestHostInfo.NetbiosName } - It "Failed to verify the CA and CN - " -Skip:$skipCN -TestCases @( + It "Failed to verify the CA and CN - " -TestCases @( @{ Scenario = 'No skips' Process = {} @@ -396,7 +405,7 @@ Describe "PSRemoting over HTTPS" { Describe "Kerberos delegation" { # macOS comes with Heimdal which by default gets a forwardable ticket - It "Connects with defaults - no delegation" -Skip:$($Global:Distribution -eq 'macOS') { + It "Connects with defaults - no delegation" -Skip:$($Global:Distribution.StartsWith('macOS')) { $invokeParams = @{ ComputerName = $Global:TestHostInfo.Hostname Credential = $Global:TestHostInfo.Credential @@ -409,8 +418,8 @@ Describe "Kerberos delegation" { $actual | Should -Not -BeLike "*forwarded*" } - # Debian 8 and Ubuntu 16.04 don't seem to read the env var config, just skip for now - It "Connects with custom krb5.conf with forwardable - " -Skip:$($Global:Distribution -in @('debian8', 'ubuntu16.04')) -TestCases @( + # Ubuntu 16.04 don't seem to read the env var config, just skip for now + It "Connects with custom krb5.conf with forwardable - " -Skip:$($Global:Distribution -in @('ubuntu16.04')) -TestCases @( @{ Authentication = 'Negotiate' }, @{ Authentication = 'Kerberos' } ) { diff --git a/psl-omi-provider/7.CMakeLanguage.diff b/psl-omi-provider/7.CMakeLanguage.diff new file mode 100644 index 000000000..585ff8143 --- /dev/null +++ b/psl-omi-provider/7.CMakeLanguage.diff @@ -0,0 +1,22 @@ +diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt +index 4cc86d1..00a2a82 100644 +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -1,5 +1,5 @@ + cmake_minimum_required(VERSION 2.8.11) +-project(PSRP) ++project(PSRP C) + + # Export commands for auto-completion engines + set(CMAKE_EXPORT_COMPILE_COMMANDS 1) +@@ -13,7 +13,9 @@ add_definitions(-D_GNU_SOURCE) + find_package(Threads REQUIRED) + + # Search OpenSSL +-if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") ++if (DEFINED ENV{OPENSSL_ROOT_DIR}) ++ message(STATUS "Using custom openssl $ENV{OPENSSL_ROOT_DIR}") ++elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) + find_package(openssl REQUIRED) + message(STATUS "Using OpenSSL ${OPENSSL_VERSION}") diff --git a/psl-omi-provider/README.md b/psl-omi-provider/README.md index 935c8be56..febce194f 100644 --- a/psl-omi-provider/README.md +++ b/psl-omi-provider/README.md @@ -12,3 +12,4 @@ Here is a list of patches that are applied during the build and what they are fo + [4.VersionInfo.diff](4.VersionInfo.diff) - Adds `PSRP_Version_Info` as an exported function and relevant build time changes to expose the version defined at build time + [5.CertificateCheck.diff](5.CertificateCheck.diff) - Pass along `-SkipCACheck` and `-SkipCNCheck` from PowerShell to support cert verification skips per connection + [6.NoChkshlibBuild.diff](6.NoChkshlibBuild.diff) - Remove requirement on uneeded OMI binary for the build ++ [7.CMakeLanguage.diff](7.CMakeLanguage.diff) - Explicitly set cmake language to C to disable C++ checks and set OpenSSL path for universal builds diff --git a/test.py b/test.py index 25cbf7c22..a5baa36d9 100755 --- a/test.py +++ b/test.py @@ -36,6 +36,9 @@ def main(): if args.docker and not distro_details['container_image']: raise ValueError("Cannot run --docker on %s as no container_image has been specified" % distribution) + # On macOS we aren't running as root in a container so this step needs sudo. + sudo_prefix = 'sudo ' if distribution.startswith('macOS') else '' + script_steps = [] if not args.skip_deps: repo_script = build_package_repo_command(distro_details['package_manager'], distro_details['microsoft_repo']) @@ -43,18 +46,12 @@ def main(): script_steps.append(('Setting up the Microsoft package manager repo', repo_script)) - if distribution == 'debian8': - debian_ms = 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-jessie-prod jessie main" > /etc/apt/sources.list.d/microsoft.list' - script_steps.append(('Further steps for MS repo on Debian 8', debian_ms)) - - elif distribution == 'debian9': + if distribution == 'debian9': debian_ms = 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-debian-stretch-prod stretch main" > /etc/apt/sources.list.d/microsoft.list' script_steps.append(('Further steps for MS repo on Debian 9', debian_ms)) script_steps.append(('Installing test dependency packages', dep_script)) - # On macOS we aren't running as root in a container so this step needs sudo. - sudo_prefix = 'sudo ' if distribution == 'macOS' else '' cert_path = os.path.join('integration_environment', 'cert_setup', 'ca.pem') if os.path.exists(os.path.join(OMI_REPO, cert_path)): cert_cmd = "%spwsh -Command 'Import-Module ./PSWSMan; Register-TrustedCertificate -Path %s -Verbose'" \ @@ -95,7 +92,7 @@ def main(): script_steps.append(('Getting libmi version', "pwsh -Command 'Import-Module ./PSWSMan; Get-WSManVersion'")) - if distribution == 'macOS': + if distribution.startswith('macOS'): script_steps.append(('Output libpsrpclient libraries', 'otool -L "${PWSHDIR}/libpsrpclient.dylib"')) script_steps.append(('Output libmi libraries', 'otool -L "${PWSHDIR}/libmi.dylib"')) diff --git a/utils.py b/utils.py index 235eb29ad..fe6af6ad0 100644 --- a/utils.py +++ b/utils.py @@ -218,13 +218,16 @@ def complete_distribution(): # type: () -> List[str] """ Finds valid distributions that this repo knows how to build for. """ distributions = [] - if sys.platform == 'darwin': - distributions.append('macOS') + on_macos = sys.platform == 'darwin' for path in os.listdir(os.path.join(OMI_REPO, 'distribution_meta')): full_path = os.path.join(OMI_REPO, 'distribution_meta', path) - if not os.path.isfile(full_path) or not path.endswith('.json') or path == 'macOS.json': + if ( + not os.path.isfile(full_path) or + not path.endswith('.json') or + (path.startswith('macOS') and not on_macos) + ): continue distributions.append(os.path.splitext(path)[0]) @@ -284,7 +287,7 @@ def load_distribution_config(distribution): # type: (str) -> Dict[str, any] required_keys = {'package_manager', 'build_deps', 'microsoft_repo', 'test_deps', 'cert_staging_dir', 'cert_staging_cmd'} - optional_keys = {'container_image', 'cert_extension', 'shell'} + optional_keys = {'container_image', 'cert_extension', 'openssl_version', 'shell'} valid_keys = required_keys.union(optional_keys) actual_keys = set(distro_details.keys())