PowerShell on macOS depends on third-party installed libraries

Created on 6 Dec 2017  路  19Comments  路  Source: PowerShell/PowerShell

In testing a clean install of PowerShell 6.0.0 on macOS 10.12, it turns out that PowerShell is specifically looking for OpenSSL libraries installed by the Homebrew package manager.

PowerShell should not depend on third party libraries wherever possible, or should include it's dependencies with the installation package.

Using otool, part of the Apple Developer Tools, against libmi.dylib shows that it has hard coded dependancies against two OpenSSL libraries in paths that are installed by Homebrew:
/usr/local/opt/openssl/lib/libssl.1.0.0.dylib
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib

Homebrew, whilst it is a convenient to use package manager, is considered to be a security risk in some contexts as it explicitly makes certain system directories group-writable and sets their owner to the current logged in user on the Mac. Two of the directories that are of concern are /usr/local/bin and /usr/local/share.

Other package managers for macOS, such as MacPorts, leave these directories owned by root:wheel as they should be and requires the use of sudo to install and manage packages. This is more secure and more in keeping with the traditional Unix way of doing things.

PowerShell however does not look in /opt for it's OpenSSL libraries which is where MacPorts will install them.

Steps to reproduce

On a clean install of macOS 10.12, install PowerShell 6.0.0-rc from the .pkg installer. Do not install it through Homebrew.

Begin a New-PSSession to Office 365. The New-PSSession will fail either with an exception or with an error that certain libraries are unable to be found.

Expected behavior

It is expected that if PowerShell is installed via a .pkg installer that this installer contains all dependencies required for PowerShell to correctly run.

Actual behavior

Executing something like:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection

either quits PowerShell completely with an unhandled exception error or it throws an error saying This parameter set requires WSMan, and no supported WSMan client library was found.

Environment data

PS /Users/kai> $PSVersionTable                                                  

Name                           Value                                           
----                           -----                                           
PSVersion                      6.0.0-rc                                        
PSEdition                      Core                                            
GitCommitId                    v6.0.0-rc                                       
OS                             Darwin 17.2.0 Darwin Kernel Version 17.2.0: F...
Platform                       Unix                                            
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                         
PSRemotingProtocolVersion      2.3                                             
SerializationVersion           1.1.0.1                                         
WSManStackVersion              3.0                                             
Area-Maintainers-Build Issue-Question OS-macOS Resolution-Duplicate Resolution-External

All 19 comments

This is only required for MI functionality and the built-in libraries don't provide that functionality. So, changing the reference to that location is not appropriate. We can write documentation on how to get these libraries and enable it yourself for the 6.0.0 release and consider making a self-contained package in the future.

That would be an acceptable solution for the 6.0.0 release. Would it be possible for PowerShell to automatically look in both the location that Homebrew uses as well as the location that MacPorts uses, as they are the two most widely used package managers for macOS. At present the library loading paths seem to be hardcoded for Homebrew only.

Based on what you're saying, I think the ideal end-state would be that:

  • Homebrew package doesn't include OpenSSL but pulls in what it needs. Homebrew users are accepting those security risks by using it (i.e. it's essentially by-design for Homebrew)
  • Standalone .pkg ships an app-local copy of the OpenSSL needed. That way users installing via .pkg are good to go. That means we're incurring a servicing burden of updating OpenSSL, though.
  • PowerShell itself should look for app-local, and then look in both the Homebrew and MacPorts locations

Thoughts?

I think that's ideal.

If end users are accepting of the conditions of using Homebrew, and are using brew to install PowerShell, then it's quite acceptable for PowerShell to rely on Homebrew's installed OpenSSL and Libcurl packages.

If someone is using MacPorts, it would be great if PowerShell could use the MacPorts versions of OpenSSL and Libcurl when installed from a .pkg. I don't know what is involved in adding a port to MacPorts, however if PowerShell were added to MacPorts, it is trivial to specify these libraries as dependancies and have MacPorts handle installing them (and keeping them up to date)

If, on the other hand, someone downloads the installer .pkg from GitHub, it would be good if it had all dependencies packaged with it, although I appreciate that you are then pulling in two third-party packages and will be responsible for keeping them up-to-date.

For what it's worth, MacPorts makes it very easy to build a .pkg installer for any of it's packages - e.g:

sudo port pkg openssl

This will build an installer pkg for OpenSSL, however AFAIK these packages sometimes are limited to being installed on the same major version of the OS (e.g. if you build on 10.13 some packages may not work on 10.12)

I believe MSFT will have many problems with shared libraries when port different applications on .Net Core. While the process is not stable we could place the shared libraries in PowerShell Core folder. (I don't know CoreFX behavior in the case). I believe it is acceptable with modern servicing model.

PS: Today I discover that nginks has -V parameter to show OpenSSL versions used and compiled with. We could do the same and show .Net, OpenSSL, curl versions for troubleshooting. Again question is for CoreFX.

I just ran into the same problem:

  • looked at Homebrew, saw the warnings, aborted installation. It felt unsafe and when I discovered this thread I felt confirmed about it. (I've never used a "package manager" and I'm not going to start now to go back into the past - I like real installer packages or, even better, the App Store.)

For me as a user, MSFT should be big enough to deliver this in the Mac App store (like they already do for other things, I just saw even the Azure Storage Explorer).

Also acceptable are PKG that include everything and just work. The current PKG installs, but when you click on the icon it just does: Nothing. Not even any error message that could help to solve the problem. Not very professional.

(but I just realized it wasn't MSFT who develops and maintains this... they linked it from their blogs makeing it look like that. So, thanks anyway for doing this work which will help at least those hard core developers out there.)

Try the following to use the MacPorts OpenSSL Libraries for PowerShell
Install MacPorts
In Terminal, type:
sudo port install openssl sudo mkdir -p /usr/local/opt/openssl/ sudo ln -s /opt/local/lib /usr/local/opt/openssl/lib
Personally, I'm OK with a command-line tool like PowerShell not coming pre-packaged with all it's dependancies as then the PowerShell maintainers also need to keep on top of keeping the 3rd party libraries up-to-date as well.

What I want is for PowerShell to use the system-installed OpenSSL libraries. I have tested PowerShell with the default Apple-installed OpenSSL libraries in /usr/lib and it works. It also works, as shown above, using the MacPorts OpenSSL libraries.

What breaks it for me is that PowerShell has the full path to the Homebrew OpenSSL libraries hard-coded into it's libraries, instead of using the default library paths on macOS.

Oh, and I believe (and am happy to be corrected if I'm wrong) that the developers of PowerShell here on GitHub are Microsoft employees - I don't think it's a third-party effort.

Also, this dependency from microsoft/omi. I filed an issue here: https://github.com/Microsoft/omi/issues/596
We don't want to fork from their codebase at least for now. So the issue needs to be fixed there first.

Powershell 7 released and still there is a dependency in libmi to openssl 1.0

otool -L /usr/local/microsoft/powershell/7/libmi.dylib
libmi.dylib:
        @rpath/libmi.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)
        /usr/lib/libpam.2.dylib (compatibility version 3.0.0, current version 3.0.0)
        /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)

This needs to be fixed because now that openssl 1.0 has been removed by the homebrew team (https://github.com/Homebrew/homebrew-cask/issues/78085), it leads to a broken experience for Mac users (https://github.com/PowerShell/PowerShell/issues/11188)

@TravisEz13 Maybe we could use C# native dll handler to resolve the issue?

We need to ensure that PowerShell has no hardcoded dynamic library paths. This is bad practice, leads to fragile configurations and can easily break with minor updates.

For example, macOS ships with OpenSSL libraries straight out of the box. Requiring the end user to install Homebrew specifically to have yet another OpenSSL library is problematic for a couple of reasons. One is that it requires the installation of more software than is strictly required. Two is that there is then another version of the OpenSSL library that needs to be kept up-to-date (or not, as the case may be if it breaks PowerShell) and can introduce security vulnerabilities if it's out of date.

On my install of macOS Catalina 10.15.3 I have the following SSL libraries in /usr/lib

-rwxr-xr-x  1 root  wheel  1482592 24 Jan 00:58 libboringssl.dylib
-rwxr-xr-x  1 root  wheel   212288 24 Jan 00:59 libssl.0.9.7.dylib
-rwxr-xr-x  1 root  wheel   335888 24 Jan 00:59 libssl.0.9.8.dylib
-rwxr-xr-x  1 root  wheel   330592 24 Jan 00:58 libssl.35.dylib
-rwxr-xr-x  1 root  wheel   314032 24 Jan 00:58 libssl.43.dylib
-rwxr-xr-x  1 root  wheel   300512 24 Jan 00:59 libssl.44.dylib
-rwxr-xr-x  1 root  wheel   294048 24 Jan 00:58 libssl.46.dylib
-rwxr-xr-x  1 root  wheel    32976 24 Jan 00:58 libssl.dylib

Can PowerShell simply use libraries that are already installed in macOS and only if Apple doesn't provide a suitable library, then fall back to requiring a third-party version?

@iSazonov This is not in PowerShell code...

I would recommend removing libmi to solve this if it didn't break DSC.

@TravisEz13 We have #8397 to track this.

This I would call this a duplicate of that issue.

I'm leaving both the duplicate and external resolution, because it's a duplicate of an issue to decouple us from an external library.

This issue has been marked as duplicate and has not had any activity for 1 day. It has been closed for housekeeping purposes.

Docs have been updated, but this is a temporary solution. Please move to SSH based remoting.
https://github.com/MicrosoftDocs/PowerShell-Docs/pull/5726

Docs have been updated, but this is a temporary solution. Please move to SSH based remoting.
MicrosoftDocs/PowerShell-Docs#5726

Regarding the above, can SSH-based remoting be used to connect to o365?
I've searched the documentation and can't find anything except for instructions to remote to another server.

@daviscyd PowerShell is in a transition phase - WinRM is frozen but ssh does still not dominate. As a result, we are all forced to experience inconvenience.

You can open new issue if you have an important scenario and have feedbacks about PowerShell 7.0 remoting.

Was this page helpful?
0 / 5 - 0 ratings