classification
Title: Write PowerShell Activate.ps1 to be static so it can be signed
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.9, Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, d3r3kk, donovick, miss-islington, paul.moore, steve.dower, tim.golden, vinay.sajip, zach.ware
Priority: normal Keywords: patch

Created on 2019-06-20 18:29 by brett.cannon, last changed 2019-08-12 21:35 by miss-islington. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 14967 merged d3r3kk, 2019-07-26 18:52
PR 15233 merged miss-islington, 2019-08-12 20:06
PR 15235 merged steve.dower, 2019-08-12 20:09
PR 15236 merged miss-islington, 2019-08-12 21:09
Messages (13)
msg346154 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2019-06-20 18:29
If Activate.ps1 was made to not have substitutions upon generation and be an entirely static file, then the file could be signed and thus not require people to lower their security requirements in PowerShell in order to activate their virtual environments.
msg346166 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2019-06-20 21:45
How would you plan to replace the functionality where the venv's bin path is substituted into the script? Purely through introspecting its own path?

I see that PowerShell is/will be portable to e.g. Linux environments, but I presume the security requirements you refer to are purely a Windows constraint - is that right?
msg346168 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2019-06-20 21:52
> How would you plan to replace the functionality where the venv's bin path is substituted into the script? Purely through introspecting its own path?

It's stored in pyvenv.cfg.

> I presume the security requirements you refer to are purely a Windows constraint - is that right?

Yes (at least for now; not sure what PowerShell Core plans to do about this sort of thing long-term).
msg346171 - (view) Author: Paul Moore (paul.moore) * (Python committer) Date: 2019-06-20 21:57
How will this interact with EnvBuilder.install_scripts() (which explicitly states that it performs textual substitution)?

Note that I'm not aware of anyone who actually uses the ability to subclass EnvBuilder, but I wouldn't be surprised to find that people do...
msg346189 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2019-06-21 07:49
> It's stored in pyvenv.cfg.

Is it?

$ python3.8maint -m venv --prompt "foo bar" /tmp/venv
$ more /tmp/venv/pyvenv.cfg 
home = /home/vinay/projects/python/3.8
include-system-site-packages = false
version = 3.8.0
prompt = 'foo bar'

The source Python location is stored, but not, from what I can see, the venv path itself ... though of course that can be worked out from $PSScriptRoot or similar.

> How will this interact with EnvBuilder.install_scripts() (which explicitly states that it performs textual substitution)?

If there's nothing to substitute (because the script source has no placeholders), that won't constitute a problem, AFAIK.
msg346216 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-06-21 13:57
One thing to note is that if we sign this file, it'll have to bypass the text substitution step completely to avoid modifying line endings or encoding. So there could be code changes in venv too.

This would be a great contribution from a PowerShell expert, and might be worth advertising (Twitter) for one. File parsing can get tricky quickly, but there are a few clever ways to approach it. We also need to set a minimum PowerShell version to support, as plenty of its features aren't available on base Windows 7 installs.
msg346236 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2019-06-21 17:08
> How will this interact with EnvBuilder.install_scripts() (which explicitly states that it performs textual substitution)?

It won't, so that would have to change as well. As you mentioned, Paul, I don't know who even uses the functionality through a subclass, but since this is a security consideration I think it's worth changing.

> Is it?

Sorry, misread what you were asking. You're right it's not stored, but it can be worked out in other ways, e.g. from the location of pyvenv.cfg or Activate.ps1, etc.

> So there could be code changes in venv too.

Yep, hence making the issue now so that others talking about adding more substitution ideas know that there's talk going the other way and removing the substitution abilities.

> This would be a great contribution from a PowerShell expert, and might be worth advertising (Twitter) for one.

Already have a co-worker interested in working on it.
msg348695 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-07-29 22:44
I just chatted with Derek about this, and while we identified some potential regressions (previously we were injecting str(prompt) into Activate.ps1, and now we're showing repr(prompt)), I don't think they're widely used.

For example, if you previously did:

>>> py -m venv --prompt "my`nprompt" env

You'd get 'my\nprompt' in pyvenv.cfg, but an actual newline in your printed prompt (note that passing "my\nprompt" in the command doesn't do this). There are likely other things that will be escaped in the configuration that previously would have been fine with the direct substitution.

I have no real sense of how widely used these are. They are definitely less popular than machines that are configured to require code-signed Powershell scripts, so we still come out ahead. It's probably easy to handle some of the more common escapes, if we know what they are, but I doubt we're going to reimplement full Python string parsing in a Powershell script.

Vinay - any thoughts here? For me, I think get it out in 3.8.0b4 and see how it fares.
msg349491 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-08-12 20:06
New changeset 732775d6be8062e72cf4995d5a9db0170e22c233 by Steve Dower (Derek Keeler) in branch 'master':
bpo-37354: Make Powershell Activate.ps1 script static to allow for signing (GH-14967)
https://github.com/python/cpython/commit/732775d6be8062e72cf4995d5a9db0170e22c233
msg349496 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-08-12 21:09
New changeset 0c64b57e0155c333b7c96ec2af009c1388cd5d31 by Steve Dower (Miss Islington (bot)) in branch '3.8':
[3.8] bpo-37354: Make Powershell Activate.ps1 script static to allow for signing (GH-14967)
https://github.com/python/cpython/commit/0c64b57e0155c333b7c96ec2af009c1388cd5d31
msg349497 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-08-12 21:09
New changeset 3e34a25a7a5c9ea2c46f2daeeb60f072faa5aaa1 by Steve Dower in branch 'master':
bpo-37354: Sign Activate.ps1 for release (GH-15235)
https://github.com/python/cpython/commit/3e34a25a7a5c9ea2c46f2daeeb60f072faa5aaa1
msg349498 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2019-08-12 21:19
Thanks, Derek!
msg349500 - (view) Author: miss-islington (miss-islington) Date: 2019-08-12 21:35
New changeset 2b98d8ec7ec3d41c6403ff9f6677a00ea0cb8b92 by Miss Islington (bot) in branch '3.8':
bpo-37354: Sign Activate.ps1 for release (GH-15235)
https://github.com/python/cpython/commit/2b98d8ec7ec3d41c6403ff9f6677a00ea0cb8b92
History
Date User Action Args
2019-08-12 21:35:22miss-islingtonsetnosy: + miss-islington
messages: + msg349500
2019-08-12 21:19:39steve.dowersetstatus: open -> closed
resolution: fixed
messages: + msg349498

stage: patch review -> resolved
2019-08-12 21:09:49miss-islingtonsetpull_requests: + pull_request14959
2019-08-12 21:09:39steve.dowersetmessages: + msg349497
2019-08-12 21:09:31steve.dowersetmessages: + msg349496
2019-08-12 20:09:01steve.dowersetpull_requests: + pull_request14958
2019-08-12 20:06:22miss-islingtonsetpull_requests: + pull_request14957
2019-08-12 20:06:06steve.dowersetmessages: + msg349491
2019-07-29 22:44:34steve.dowersetmessages: + msg348695
versions: + Python 3.8
2019-07-29 22:38:40d3r3kksetnosy: + d3r3kk
2019-07-26 18:52:27d3r3kksetkeywords: + patch
stage: needs patch -> patch review
pull_requests: + pull_request14735
2019-06-21 17:08:38brett.cannonsetversions: + Python 3.9
2019-06-21 17:08:34brett.cannonsetmessages: + msg346236
2019-06-21 13:57:15steve.dowersetmessages: + msg346216
2019-06-21 07:49:53vinay.sajipsetmessages: + msg346189
2019-06-20 21:57:41paul.mooresetmessages: + msg346171
2019-06-20 21:52:23brett.cannonsetmessages: + msg346168
2019-06-20 21:45:14vinay.sajipsetmessages: + msg346166
2019-06-20 20:01:05donovicksetnosy: + donovick
2019-06-20 18:29:29brett.cannoncreate