mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge 3006.x into 3007.x
This commit is contained in:
commit
e5d3ef7ff7
39 changed files with 19262 additions and 12499 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
@ -1995,6 +1995,7 @@ jobs:
|
||||||
nox --force-color -e create-xml-coverage-reports
|
nox --force-color -e create-xml-coverage-reports
|
||||||
|
|
||||||
- name: Upload Code Coverage To Codecov
|
- name: Upload Code Coverage To Codecov
|
||||||
|
if: ${{ ! github.event.repository.private }}
|
||||||
run: |
|
run: |
|
||||||
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
||||||
|
|
||||||
|
|
1
.github/workflows/nightly.yml
vendored
1
.github/workflows/nightly.yml
vendored
|
@ -2055,6 +2055,7 @@ jobs:
|
||||||
nox --force-color -e create-xml-coverage-reports
|
nox --force-color -e create-xml-coverage-reports
|
||||||
|
|
||||||
- name: Upload Code Coverage To Codecov
|
- name: Upload Code Coverage To Codecov
|
||||||
|
if: ${{ ! github.event.repository.private }}
|
||||||
run: |
|
run: |
|
||||||
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
||||||
|
|
||||||
|
|
1
.github/workflows/scheduled.yml
vendored
1
.github/workflows/scheduled.yml
vendored
|
@ -2037,6 +2037,7 @@ jobs:
|
||||||
nox --force-color -e create-xml-coverage-reports
|
nox --force-color -e create-xml-coverage-reports
|
||||||
|
|
||||||
- name: Upload Code Coverage To Codecov
|
- name: Upload Code Coverage To Codecov
|
||||||
|
if: ${{ ! github.event.repository.private }}
|
||||||
run: |
|
run: |
|
||||||
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
||||||
|
|
||||||
|
|
1
.github/workflows/templates/ci.yml.jinja
vendored
1
.github/workflows/templates/ci.yml.jinja
vendored
|
@ -376,6 +376,7 @@
|
||||||
nox --force-color -e create-xml-coverage-reports
|
nox --force-color -e create-xml-coverage-reports
|
||||||
|
|
||||||
- name: Upload Code Coverage To Codecov
|
- name: Upload Code Coverage To Codecov
|
||||||
|
if: ${{ ! github.event.repository.private }}
|
||||||
run: |
|
run: |
|
||||||
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
tools ci upload-coverage --commit-sha=${{ github.event.pull_request.head.sha || github.sha }} artifacts/coverage/
|
||||||
|
|
||||||
|
|
41
CHANGELOG.md
41
CHANGELOG.md
|
@ -179,7 +179,48 @@ Versions are `MAJOR.PATCH`.
|
||||||
- Update to `gitpython>=3.1.35` due to https://github.com/advisories/GHSA-wfm5-v35h-vwf4 and https://github.com/advisories/GHSA-cwvm-v4w8-q58c [#65137](https://github.com/saltstack/salt/issues/65137)
|
- Update to `gitpython>=3.1.35` due to https://github.com/advisories/GHSA-wfm5-v35h-vwf4 and https://github.com/advisories/GHSA-cwvm-v4w8-q58c [#65137](https://github.com/saltstack/salt/issues/65137)
|
||||||
|
|
||||||
|
|
||||||
|
## 3006.6 (2024-01-26)
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Salt no longer time bombs user installations on code using `salt.utils.versions.warn_until_date` [#665924](https://github.com/saltstack/salt/issues/665924)
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix un-closed transport in tornado netapi [#65759](https://github.com/saltstack/salt/issues/65759)
|
||||||
|
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- CVE-2024-22231 Prevent directory traversal when creating syndic cache directory on the master
|
||||||
|
CVE-2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
These vulerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) [#565](https://github.com/saltstack/salt/issues/565)
|
||||||
|
- Update some requirements which had some security issues:
|
||||||
|
|
||||||
|
* Bump to `pycryptodome==3.19.1` and `pycryptodomex==3.19.1` due to https://github.com/advisories/GHSA-j225-cvw7-qrx7
|
||||||
|
* Bump to `gitpython==3.1.41` due to https://github.com/advisories/GHSA-2mqj-m65w-jghx
|
||||||
|
* Bump to `jinja2==3.1.3` due to https://github.com/advisories/GHSA-h5c8-rqwp-cp95 [#65830](https://github.com/saltstack/salt/issues/65830)
|
||||||
|
|
||||||
|
|
||||||
## 3006.5 (2023-12-12)
|
## 3006.5 (2023-12-12)
|
||||||
|
Salt 3005.5 (2024-01-19)
|
||||||
|
========================
|
||||||
|
|
||||||
|
Security
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix CVE-2024-22231 Prevent directory traversal when creating syndic cache directory on the master.
|
||||||
|
- Fix CVE-2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
|
||||||
|
These vulnerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) (#565)
|
||||||
|
|
||||||
|
|
||||||
|
Salt v3005.4 (2023-10-16)
|
||||||
|
=========================
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
1
changelog/52289.fixed.md
Normal file
1
changelog/52289.fixed.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Fixed an issue when keys didn't match because of line endings
|
|
@ -1 +0,0 @@
|
||||||
Fix un-closed transport in tornado netapi
|
|
|
@ -1,5 +0,0 @@
|
||||||
Update some requirements which had some security issues:
|
|
||||||
|
|
||||||
* Bump to `pycryptodome==3.19.1` and `pycryptodomex==3.19.1` due to https://github.com/advisories/GHSA-j225-cvw7-qrx7
|
|
||||||
* Bump to `gitpython==3.1.41` due to https://github.com/advisories/GHSA-2mqj-m65w-jghx
|
|
||||||
* Bump to `jinja2==3.1.3` due to https://github.com/advisories/GHSA-h5c8-rqwp-cp95
|
|
|
@ -1 +0,0 @@
|
||||||
Salt no longer time bombs user installations on code using `salt.utils.versions.warn_until_date`
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-API" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-API" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-api \- salt-api Command
|
salt-api \- salt-api Command
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-CALL" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-CALL" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-call \- salt-call Documentation
|
salt-call \- salt-call Documentation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-CLOUD" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-CLOUD" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-cloud \- Salt Cloud Command
|
salt-cloud \- Salt Cloud Command
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-CP" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-CP" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-cp \- salt-cp Documentation
|
salt-cp \- salt-cp Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-KEY" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-KEY" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-key \- salt-key Documentation
|
salt-key \- salt-key Documentation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-MASTER" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-MASTER" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-master \- salt-master Documentation
|
salt-master \- salt-master Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-MINION" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-MINION" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-minion \- salt-minion Documentation
|
salt-minion \- salt-minion Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-PROXY" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-PROXY" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-proxy \- salt-proxy Documentation
|
salt-proxy \- salt-proxy Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-RUN" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-RUN" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-run \- salt-run Documentation
|
salt-run \- salt-run Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-SSH" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-SSH" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-ssh \- salt-ssh Documentation
|
salt-ssh \- salt-ssh Documentation
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT-SYNDIC" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT-SYNDIC" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt-syndic \- salt-syndic Documentation
|
salt-syndic \- salt-syndic Documentation
|
||||||
.sp
|
.sp
|
||||||
|
|
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SALT" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SALT" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
salt \- salt
|
salt \- salt
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
|
|
31162
doc/man/salt.7
31162
doc/man/salt.7
File diff suppressed because it is too large
Load diff
|
@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||||
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||||||
..
|
..
|
||||||
.TH "SPM" "1" "Generated on January 02, 2024 at 09:39:27 PM UTC." "3007.0" "Salt"
|
.TH "SPM" "1" "Generated on January 26, 2024 at 11:57:28 AM UTC." "3006.6" "Salt"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
spm \- Salt Package Manager Command
|
spm \- Salt Package Manager Command
|
||||||
.sp
|
.sp
|
||||||
|
|
16
doc/topics/releases/3005.5.rst
Normal file
16
doc/topics/releases/3005.5.rst
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
.. _release-3005-5:
|
||||||
|
|
||||||
|
=========================
|
||||||
|
Salt 3005.5 Release Notes
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Version 3005.5 is a CVE security fix release for :ref:`3005 <release-3005>`.
|
||||||
|
|
||||||
|
Security
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix CVE-2024-22231 by preventing directory traversal when creating syndic cache directory on the master.
|
||||||
|
- Fix CVE-2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
|
||||||
|
These vulnerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) (#565)
|
41
doc/topics/releases/3006.6.md
Normal file
41
doc/topics/releases/3006.6.md
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
(release-3006.6)=
|
||||||
|
# Salt 3006.6 release notes
|
||||||
|
|
||||||
|
<!---
|
||||||
|
Do not edit this file. This is auto generated.
|
||||||
|
Edit the templates in doc/topics/releases/templates/
|
||||||
|
for a given release.
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Add release specific details below
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Do not edit the changelog below.
|
||||||
|
This is auto generated.
|
||||||
|
-->
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Salt no longer time bombs user installations on code using `salt.utils.versions.warn_until_date` [#665924](https://github.com/saltstack/salt/issues/665924)
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix un-closed transport in tornado netapi [#65759](https://github.com/saltstack/salt/issues/65759)
|
||||||
|
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
- CVE-2024-22231 Prevent directory traversal when creating syndic cache directory on the master
|
||||||
|
CVE-2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
These vulerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) [#565](https://github.com/saltstack/salt/issues/565)
|
||||||
|
- Update some requirements which had some security issues:
|
||||||
|
|
||||||
|
* Bump to `pycryptodome==3.19.1` and `pycryptodomex==3.19.1` due to https://github.com/advisories/GHSA-j225-cvw7-qrx7
|
||||||
|
* Bump to `gitpython==3.1.41` due to https://github.com/advisories/GHSA-2mqj-m65w-jghx
|
||||||
|
* Bump to `jinja2==3.1.3` due to https://github.com/advisories/GHSA-h5c8-rqwp-cp95 [#65830](https://github.com/saltstack/salt/issues/65830)
|
14
doc/topics/releases/templates/3006.6.md.template
Normal file
14
doc/topics/releases/templates/3006.6.md.template
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
(release-3006.6)=
|
||||||
|
# Salt 3006.6 release notes{{ unreleased }}
|
||||||
|
{{ warning }}
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Add release specific details below
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Do not edit the changelog below.
|
||||||
|
This is auto generated.
|
||||||
|
-->
|
||||||
|
## Changelog
|
||||||
|
{{ changelog }}
|
|
@ -1,3 +1,29 @@
|
||||||
|
salt (3006.6) stable; urgency=medium
|
||||||
|
|
||||||
|
|
||||||
|
# Changed
|
||||||
|
|
||||||
|
* Salt no longer time bombs user installations on code using `salt.utils.versions.warn_until_date` [#665924](https://github.com/saltstack/salt/issues/665924)
|
||||||
|
|
||||||
|
# Fixed
|
||||||
|
|
||||||
|
* Fix un-closed transport in tornado netapi [#65759](https://github.com/saltstack/salt/issues/65759)
|
||||||
|
|
||||||
|
# Security
|
||||||
|
|
||||||
|
* CVE-2024-22231 Prevent directory traversal when creating syndic cache directory on the master
|
||||||
|
CVE*2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
These vulerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) [#565](https://github.com/saltstack/salt/issues/565)
|
||||||
|
* Update some requirements which had some security issues:
|
||||||
|
|
||||||
|
* Bump to `pycryptodome==3.19.1` and `pycryptodomex==3.19.1` due to https://github.com/advisories/GHSA*j225-cvw7-qrx7
|
||||||
|
* Bump to `gitpython==3.1.41` due to https://github.com/advisories/GHSA*2mqj-m65w-jghx
|
||||||
|
* Bump to `jinja2==3.1.3` due to https://github.com/advisories/GHSA*h5c8-rqwp-cp95 [#65830](https://github.com/saltstack/salt/issues/65830)
|
||||||
|
|
||||||
|
|
||||||
|
-- Salt Project Packaging <saltproject-packaging@vmware.com> Fri, 26 Jan 2024 11:56:46 +0000
|
||||||
|
|
||||||
salt (3007.0rc1) stable; urgency=medium
|
salt (3007.0rc1) stable; urgency=medium
|
||||||
|
|
||||||
|
|
||||||
|
@ -167,6 +193,7 @@ salt (3007.0rc1) stable; urgency=medium
|
||||||
|
|
||||||
-- Salt Project Packaging <saltproject-packaging@vmware.com> Tue, 02 Jan 2024 21:36:56 +0000
|
-- Salt Project Packaging <saltproject-packaging@vmware.com> Tue, 02 Jan 2024 21:36:56 +0000
|
||||||
|
|
||||||
|
|
||||||
salt (3006.5) stable; urgency=medium
|
salt (3006.5) stable; urgency=medium
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -583,6 +583,29 @@ fi
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Jan 26 2024 Salt Project Packaging <saltproject-packaging@vmware.com> - 3006.6
|
||||||
|
|
||||||
|
# Changed
|
||||||
|
|
||||||
|
- Salt no longer time bombs user installations on code using `salt.utils.versions.warn_until_date` [#665924](https://github.com/saltstack/salt/issues/665924)
|
||||||
|
|
||||||
|
# Fixed
|
||||||
|
|
||||||
|
- Fix un-closed transport in tornado netapi [#65759](https://github.com/saltstack/salt/issues/65759)
|
||||||
|
|
||||||
|
# Security
|
||||||
|
|
||||||
|
- CVE-2024-22231 Prevent directory traversal when creating syndic cache directory on the master
|
||||||
|
CVE-2024-22232 Prevent directory traversal attacks in the master's serve_file method.
|
||||||
|
These vulerablities were discovered and reported by:
|
||||||
|
Yudi Zhao(Huawei Nebula Security Lab),Chenwei Jiang(Huawei Nebula Security Lab) [#565](https://github.com/saltstack/salt/issues/565)
|
||||||
|
- Update some requirements which had some security issues:
|
||||||
|
|
||||||
|
* Bump to `pycryptodome==3.19.1` and `pycryptodomex==3.19.1` due to https://github.com/advisories/GHSA-j225-cvw7-qrx7
|
||||||
|
* Bump to `gitpython==3.1.41` due to https://github.com/advisories/GHSA-2mqj-m65w-jghx
|
||||||
|
* Bump to `jinja2==3.1.3` due to https://github.com/advisories/GHSA-h5c8-rqwp-cp95 [#65830](https://github.com/saltstack/salt/issues/65830)
|
||||||
|
|
||||||
|
|
||||||
* Tue Jan 02 2024 Salt Project Packaging <saltproject-packaging@vmware.com> - 3007.0~rc1
|
* Tue Jan 02 2024 Salt Project Packaging <saltproject-packaging@vmware.com> - 3007.0~rc1
|
||||||
|
|
||||||
# Removed
|
# Removed
|
||||||
|
@ -749,6 +772,7 @@ fi
|
||||||
- Update to `gitpython>=3.1.35` due to https://github.com/advisories/GHSA-wfm5-v35h-vwf4 and https://github.com/advisories/GHSA-cwvm-v4w8-q58c [#65137](https://github.com/saltstack/salt/issues/65137)
|
- Update to `gitpython>=3.1.35` due to https://github.com/advisories/GHSA-wfm5-v35h-vwf4 and https://github.com/advisories/GHSA-cwvm-v4w8-q58c [#65137](https://github.com/saltstack/salt/issues/65137)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* Tue Dec 12 2023 Salt Project Packaging <saltproject-packaging@vmware.com> - 3006.5
|
* Tue Dec 12 2023 Salt Project Packaging <saltproject-packaging@vmware.com> - 3006.5
|
||||||
|
|
||||||
# Removed
|
# Removed
|
||||||
|
|
|
@ -56,6 +56,10 @@ class ReqServerChannel:
|
||||||
transport = salt.transport.request_server(opts, **kwargs)
|
transport = salt.transport.request_server(opts, **kwargs)
|
||||||
return cls(opts, transport)
|
return cls(opts, transport)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _clean_key(key):
|
||||||
|
return key.strip().replace("\r", "").replace("\n", "")
|
||||||
|
|
||||||
def __init__(self, opts, transport):
|
def __init__(self, opts, transport):
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
|
@ -381,7 +385,7 @@ class ReqServerChannel:
|
||||||
elif os.path.isfile(pubfn):
|
elif os.path.isfile(pubfn):
|
||||||
# The key has been accepted, check it
|
# The key has been accepted, check it
|
||||||
with salt.utils.files.fopen(pubfn, "r") as pubfn_handle:
|
with salt.utils.files.fopen(pubfn, "r") as pubfn_handle:
|
||||||
if pubfn_handle.read().strip() != load["pub"].strip():
|
if self._clean_key(pubfn_handle.read()) != self._clean_key(load["pub"]):
|
||||||
log.error(
|
log.error(
|
||||||
"Authentication attempt from %s failed, the public "
|
"Authentication attempt from %s failed, the public "
|
||||||
"keys did not match. This may be an attempt to compromise "
|
"keys did not match. This may be an attempt to compromise "
|
||||||
|
@ -490,7 +494,9 @@ class ReqServerChannel:
|
||||||
# case. Otherwise log the fact that the minion is still
|
# case. Otherwise log the fact that the minion is still
|
||||||
# pending.
|
# pending.
|
||||||
with salt.utils.files.fopen(pubfn_pend, "r") as pubfn_handle:
|
with salt.utils.files.fopen(pubfn_pend, "r") as pubfn_handle:
|
||||||
if pubfn_handle.read() != load["pub"]:
|
if self._clean_key(pubfn_handle.read()) != self._clean_key(
|
||||||
|
load["pub"]
|
||||||
|
):
|
||||||
log.error(
|
log.error(
|
||||||
"Authentication attempt from %s failed, the public "
|
"Authentication attempt from %s failed, the public "
|
||||||
"key in pending did not match. This may be an "
|
"key in pending did not match. This may be an "
|
||||||
|
@ -546,7 +552,9 @@ class ReqServerChannel:
|
||||||
# so, pass on doing anything here, and let it get automatically
|
# so, pass on doing anything here, and let it get automatically
|
||||||
# accepted below.
|
# accepted below.
|
||||||
with salt.utils.files.fopen(pubfn_pend, "r") as pubfn_handle:
|
with salt.utils.files.fopen(pubfn_pend, "r") as pubfn_handle:
|
||||||
if pubfn_handle.read() != load["pub"]:
|
if self._clean_key(pubfn_handle.read()) != self._clean_key(
|
||||||
|
load["pub"]
|
||||||
|
):
|
||||||
log.error(
|
log.error(
|
||||||
"Authentication attempt from %s failed, the public "
|
"Authentication attempt from %s failed, the public "
|
||||||
"keys in pending did not match. This may be an "
|
"keys in pending did not match. This may be an "
|
||||||
|
|
|
@ -568,11 +568,6 @@ class Fileserver:
|
||||||
saltenv = salt.utils.stringutils.to_unicode(saltenv)
|
saltenv = salt.utils.stringutils.to_unicode(saltenv)
|
||||||
back = self.backends(back)
|
back = self.backends(back)
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
fnd = {"path": "", "rel": ""}
|
|
||||||
if os.path.isabs(path):
|
|
||||||
return fnd
|
|
||||||
if "../" in path:
|
|
||||||
return fnd
|
|
||||||
if salt.utils.url.is_escaped(path):
|
if salt.utils.url.is_escaped(path):
|
||||||
# don't attempt to find URL query arguments in the path
|
# don't attempt to find URL query arguments in the path
|
||||||
path = salt.utils.url.unescape(path)
|
path = salt.utils.url.unescape(path)
|
||||||
|
@ -588,6 +583,10 @@ class Fileserver:
|
||||||
args = comp.split("=", 1)
|
args = comp.split("=", 1)
|
||||||
kwargs[args[0]] = args[1]
|
kwargs[args[0]] = args[1]
|
||||||
|
|
||||||
|
fnd = {"path": "", "rel": ""}
|
||||||
|
if os.path.isabs(path) or "../" in path:
|
||||||
|
return fnd
|
||||||
|
|
||||||
if "env" in kwargs:
|
if "env" in kwargs:
|
||||||
# "env" is not supported; Use "saltenv".
|
# "env" is not supported; Use "saltenv".
|
||||||
kwargs.pop("env")
|
kwargs.pop("env")
|
||||||
|
|
|
@ -27,6 +27,7 @@ import salt.utils.hashutils
|
||||||
import salt.utils.path
|
import salt.utils.path
|
||||||
import salt.utils.platform
|
import salt.utils.platform
|
||||||
import salt.utils.stringutils
|
import salt.utils.stringutils
|
||||||
|
import salt.utils.verify
|
||||||
import salt.utils.versions
|
import salt.utils.versions
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -98,6 +99,11 @@ def find_file(path, saltenv="base", **kwargs):
|
||||||
if saltenv == "__env__":
|
if saltenv == "__env__":
|
||||||
root = root.replace("__env__", actual_saltenv)
|
root = root.replace("__env__", actual_saltenv)
|
||||||
full = os.path.join(root, path)
|
full = os.path.join(root, path)
|
||||||
|
|
||||||
|
# Refuse to serve file that is not under the root.
|
||||||
|
if not salt.utils.verify.clean_path(root, full, subdir=True):
|
||||||
|
continue
|
||||||
|
|
||||||
if os.path.isfile(full) and not salt.fileserver.is_file_ignored(__opts__, full):
|
if os.path.isfile(full) and not salt.fileserver.is_file_ignored(__opts__, full):
|
||||||
fnd["path"] = full
|
fnd["path"] = full
|
||||||
fnd["rel"] = path
|
fnd["rel"] = path
|
||||||
|
@ -128,6 +134,26 @@ def serve_file(load, fnd):
|
||||||
ret["dest"] = fnd["rel"]
|
ret["dest"] = fnd["rel"]
|
||||||
gzip = load.get("gzip", None)
|
gzip = load.get("gzip", None)
|
||||||
fpath = os.path.normpath(fnd["path"])
|
fpath = os.path.normpath(fnd["path"])
|
||||||
|
|
||||||
|
actual_saltenv = saltenv = load["saltenv"]
|
||||||
|
if saltenv not in __opts__["file_roots"]:
|
||||||
|
if "__env__" in __opts__["file_roots"]:
|
||||||
|
log.debug(
|
||||||
|
"salt environment '%s' maps to __env__ file_roots directory", saltenv
|
||||||
|
)
|
||||||
|
saltenv = "__env__"
|
||||||
|
else:
|
||||||
|
return fnd
|
||||||
|
file_in_root = False
|
||||||
|
for root in __opts__["file_roots"][saltenv]:
|
||||||
|
if saltenv == "__env__":
|
||||||
|
root = root.replace("__env__", actual_saltenv)
|
||||||
|
# Refuse to serve file that is not under the root.
|
||||||
|
if salt.utils.verify.clean_path(root, fpath, subdir=True):
|
||||||
|
file_in_root = True
|
||||||
|
if not file_in_root:
|
||||||
|
return ret
|
||||||
|
|
||||||
with salt.utils.files.fopen(fpath, "rb") as fp_:
|
with salt.utils.files.fopen(fpath, "rb") as fp_:
|
||||||
fp_.seek(load["loc"])
|
fp_.seek(load["loc"])
|
||||||
data = fp_.read(__opts__["file_buffer_size"])
|
data = fp_.read(__opts__["file_buffer_size"])
|
||||||
|
|
|
@ -1901,10 +1901,16 @@ class AESFuncs(TransportMethods):
|
||||||
self.mminion.returners[fstr](load["jid"], load["load"])
|
self.mminion.returners[fstr](load["jid"], load["load"])
|
||||||
|
|
||||||
# Register the syndic
|
# Register the syndic
|
||||||
|
|
||||||
|
# We are creating a path using user suplied input. Use the
|
||||||
|
# clean_path to prevent a directory traversal.
|
||||||
|
root = os.path.join(self.opts["cachedir"], "syndics")
|
||||||
syndic_cache_path = os.path.join(
|
syndic_cache_path = os.path.join(
|
||||||
self.opts["cachedir"], "syndics", load["id"]
|
self.opts["cachedir"], "syndics", load["id"]
|
||||||
)
|
)
|
||||||
if not os.path.exists(syndic_cache_path):
|
if salt.utils.verify.clean_path(
|
||||||
|
root, syndic_cache_path
|
||||||
|
) and not os.path.exists(syndic_cache_path):
|
||||||
path_name = os.path.split(syndic_cache_path)[0]
|
path_name = os.path.split(syndic_cache_path)[0]
|
||||||
if not os.path.exists(path_name):
|
if not os.path.exists(path_name):
|
||||||
os.makedirs(path_name)
|
os.makedirs(path_name)
|
||||||
|
|
35
tests/pytests/unit/channel/test_server.py
Normal file
35
tests/pytests/unit/channel/test_server.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
import salt.channel.server as server
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def key_data():
|
||||||
|
return [
|
||||||
|
"-----BEGIN PUBLIC KEY-----",
|
||||||
|
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoe5QSDYRWKyknbVyRrIj",
|
||||||
|
"rm1ht5HgKzAVUber0x54+b/UgxTd1cqI6I+eDlx53LqZSH3G8Rd5cUh8LHoGedSa",
|
||||||
|
"E62vEiLAjgXa+RdgcGiQpYS8+Z2RvQJ8oIcZgO+2AzgBRHboNWHTYRRmJXCd3dKs",
|
||||||
|
"9tcwK6wxChR06HzGqaOTixAuQlegWbOTU+X4dXIbW7AnuQBt9MCib7SxHlscrqcS",
|
||||||
|
"cBrRvq51YP6cxPm/rZJdBqZhVrlghBvIpa45NApP5PherGi4AbEGYte4l+gC+fOA",
|
||||||
|
"osEBis1V27djPpIyQS4qk3XAPQg6CYQMDltHqA4Fdo0Nt7SMScxJhfH0r6zmBFAe",
|
||||||
|
"BQIDAQAB",
|
||||||
|
"-----END PUBLIC KEY-----",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("linesep", ["\r\n", "\r", "\n"])
|
||||||
|
def test__clean_key(key_data, linesep):
|
||||||
|
tst_key = linesep.join(key_data)
|
||||||
|
chk_key = "\n".join(key_data)
|
||||||
|
clean_func = server.ReqServerChannel._clean_key
|
||||||
|
assert clean_func(tst_key) == clean_func(chk_key)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("linesep", ["\r\n", "\r", "\n"])
|
||||||
|
def test__clean_key_mismatch(key_data, linesep):
|
||||||
|
tst_key = linesep.join(key_data)
|
||||||
|
tst_key = tst_key.replace("5", "4")
|
||||||
|
chk_key = "\n".join(key_data)
|
||||||
|
clean_func = server.ReqServerChannel._clean_key
|
||||||
|
assert clean_func(tst_key) != clean_func(chk_key)
|
|
@ -5,6 +5,7 @@
|
||||||
import copy
|
import copy
|
||||||
import pathlib
|
import pathlib
|
||||||
import shutil
|
import shutil
|
||||||
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -28,14 +29,14 @@ def unicode_dirname():
|
||||||
return "соль"
|
return "соль"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture
|
||||||
def testfile(tmp_path):
|
def testfile(tmp_path):
|
||||||
fp = tmp_path / "testfile"
|
fp = tmp_path / "testfile"
|
||||||
fp.write_text("This is a testfile")
|
fp.write_text("This is a testfile")
|
||||||
return fp
|
return fp
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture
|
||||||
def tmp_state_tree(tmp_path, testfile, unicode_filename, unicode_dirname):
|
def tmp_state_tree(tmp_path, testfile, unicode_filename, unicode_dirname):
|
||||||
dirname = tmp_path / "roots_tmp_state_tree"
|
dirname = tmp_path / "roots_tmp_state_tree"
|
||||||
dirname.mkdir(parents=True, exist_ok=True)
|
dirname.mkdir(parents=True, exist_ok=True)
|
||||||
|
@ -54,11 +55,15 @@ def tmp_state_tree(tmp_path, testfile, unicode_filename, unicode_dirname):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def configure_loader_modules(tmp_state_tree, temp_salt_master):
|
def testfilepath(tmp_state_tree, testfile):
|
||||||
opts = temp_salt_master.config.copy()
|
return tmp_state_tree / testfile.name
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def configure_loader_modules(tmp_state_tree, master_opts):
|
||||||
overrides = {"file_roots": {"base": [str(tmp_state_tree)]}}
|
overrides = {"file_roots": {"base": [str(tmp_state_tree)]}}
|
||||||
opts.update(overrides)
|
master_opts.update(overrides)
|
||||||
return {roots: {"__opts__": opts}}
|
return {roots: {"__opts__": master_opts}}
|
||||||
|
|
||||||
|
|
||||||
def test_file_list(unicode_filename):
|
def test_file_list(unicode_filename):
|
||||||
|
@ -75,17 +80,17 @@ def test_find_file(tmp_state_tree):
|
||||||
assert full_path_to_file == ret["path"]
|
assert full_path_to_file == ret["path"]
|
||||||
|
|
||||||
|
|
||||||
def test_serve_file(testfile):
|
def test_serve_file(testfilepath):
|
||||||
with patch.dict(roots.__opts__, {"file_buffer_size": 262144}):
|
with patch.dict(roots.__opts__, {"file_buffer_size": 262144}):
|
||||||
load = {
|
load = {
|
||||||
"saltenv": "base",
|
"saltenv": "base",
|
||||||
"path": str(testfile),
|
"path": str(testfilepath),
|
||||||
"loc": 0,
|
"loc": 0,
|
||||||
}
|
}
|
||||||
fnd = {"path": str(testfile), "rel": "testfile"}
|
fnd = {"path": str(testfilepath), "rel": "testfile"}
|
||||||
ret = roots.serve_file(load, fnd)
|
ret = roots.serve_file(load, fnd)
|
||||||
|
|
||||||
with salt.utils.files.fopen(str(testfile), "rb") as fp_:
|
with salt.utils.files.fopen(str(testfilepath), "rb") as fp_:
|
||||||
data = fp_.read()
|
data = fp_.read()
|
||||||
|
|
||||||
assert ret == {"data": data, "dest": "testfile"}
|
assert ret == {"data": data, "dest": "testfile"}
|
||||||
|
@ -236,7 +241,7 @@ def test_update_mtime_map():
|
||||||
# between Python releases.
|
# between Python releases.
|
||||||
lines_written = sorted(mtime_map_mock.write_calls())
|
lines_written = sorted(mtime_map_mock.write_calls())
|
||||||
expected = sorted(
|
expected = sorted(
|
||||||
salt.utils.stringutils.to_bytes("{key}:{val}\n".format(key=key, val=val))
|
salt.utils.stringutils.to_bytes(f"{key}:{val}\n")
|
||||||
for key, val in new_mtime_map.items()
|
for key, val in new_mtime_map.items()
|
||||||
)
|
)
|
||||||
assert lines_written == expected, lines_written
|
assert lines_written == expected, lines_written
|
||||||
|
@ -277,3 +282,36 @@ def test_update_mtime_map_unicode_error(tmp_path):
|
||||||
},
|
},
|
||||||
"backend": "roots",
|
"backend": "roots",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_file_not_in_root(tmp_state_tree):
|
||||||
|
"""
|
||||||
|
Fileroots should never 'find' a file that is outside of it's root.
|
||||||
|
"""
|
||||||
|
badfile = pathlib.Path(tmp_state_tree).parent / "bar"
|
||||||
|
badfile.write_text("Bad file")
|
||||||
|
badpath = f"../bar"
|
||||||
|
ret = roots.find_file(badpath)
|
||||||
|
assert ret == {"path": "", "rel": ""}
|
||||||
|
badpath = f"{tmp_state_tree / '..' / 'bar'}"
|
||||||
|
ret = roots.find_file(badpath)
|
||||||
|
assert ret == {"path": "", "rel": ""}
|
||||||
|
|
||||||
|
|
||||||
|
def test_serve_file_not_in_root(tmp_state_tree):
|
||||||
|
"""
|
||||||
|
Fileroots should never 'serve' a file that is outside of it's root.
|
||||||
|
"""
|
||||||
|
badfile = pathlib.Path(tmp_state_tree).parent / "bar"
|
||||||
|
badfile.write_text("Bad file")
|
||||||
|
badpath = f"../bar"
|
||||||
|
load = {"path": "salt://|..\\bar", "saltenv": "base", "loc": 0}
|
||||||
|
fnd = {
|
||||||
|
"path": f"{tmp_state_tree / '..' / 'bar'}",
|
||||||
|
"rel": f"{pathlib.Path('..') / 'bar'}",
|
||||||
|
}
|
||||||
|
ret = roots.serve_file(load, fnd)
|
||||||
|
if "win" in sys.platform:
|
||||||
|
assert ret == {"data": "", "dest": "..\\bar"}
|
||||||
|
else:
|
||||||
|
assert ret == {"data": "", "dest": "../bar"}
|
||||||
|
|
123
tests/pytests/unit/test_fileserver.py
Normal file
123
tests/pytests/unit/test_fileserver.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
import salt.fileserver
|
||||||
|
import salt.utils.files
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_with_diffent_keys():
|
||||||
|
"""
|
||||||
|
Test that different maps are indeed reported different
|
||||||
|
"""
|
||||||
|
map1 = {"file1": 1234}
|
||||||
|
map2 = {"file2": 1234}
|
||||||
|
assert salt.fileserver.diff_mtime_map(map1, map2) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_diff_with_diffent_values():
|
||||||
|
"""
|
||||||
|
Test that different maps are indeed reported different
|
||||||
|
"""
|
||||||
|
map1 = {"file1": 12345}
|
||||||
|
map2 = {"file1": 1234}
|
||||||
|
assert salt.fileserver.diff_mtime_map(map1, map2) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_whitelist():
|
||||||
|
opts = {
|
||||||
|
"fileserver_backend": ["roots", "git", "s3fs", "hgfs", "svn"],
|
||||||
|
"extension_modules": "",
|
||||||
|
}
|
||||||
|
fs = salt.fileserver.Fileserver(opts)
|
||||||
|
assert sorted(fs.servers.whitelist) == sorted(
|
||||||
|
["git", "gitfs", "hg", "hgfs", "svn", "svnfs", "roots", "s3fs"]
|
||||||
|
), fs.servers.whitelist
|
||||||
|
|
||||||
|
|
||||||
|
def test_future_file_list_cache_file_ignored(tmp_path):
|
||||||
|
opts = {
|
||||||
|
"fileserver_backend": ["roots"],
|
||||||
|
"cachedir": tmp_path,
|
||||||
|
"extension_modules": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
back_cachedir = os.path.join(tmp_path, "file_lists/roots")
|
||||||
|
os.makedirs(os.path.join(back_cachedir))
|
||||||
|
|
||||||
|
# Touch a couple files
|
||||||
|
for filename in ("base.p", "foo.txt"):
|
||||||
|
with salt.utils.files.fopen(os.path.join(back_cachedir, filename), "wb") as _f:
|
||||||
|
if filename == "base.p":
|
||||||
|
_f.write(b"\x80")
|
||||||
|
|
||||||
|
# Set modification time to file list cache file to 1 year in the future
|
||||||
|
now = datetime.datetime.utcnow()
|
||||||
|
future = now + datetime.timedelta(days=365)
|
||||||
|
mod_time = time.mktime(future.timetuple())
|
||||||
|
os.utime(os.path.join(back_cachedir, "base.p"), (mod_time, mod_time))
|
||||||
|
|
||||||
|
list_cache = os.path.join(back_cachedir, "base.p")
|
||||||
|
w_lock = os.path.join(back_cachedir, ".base.w")
|
||||||
|
ret = salt.fileserver.check_file_list_cache(opts, "files", list_cache, w_lock)
|
||||||
|
assert (
|
||||||
|
ret[1] is True
|
||||||
|
), "Cache file list cache file is not refreshed when future modification time"
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_server_url_escape(tmp_path):
|
||||||
|
(tmp_path / "srv").mkdir()
|
||||||
|
(tmp_path / "srv" / "salt").mkdir()
|
||||||
|
(tmp_path / "foo").mkdir()
|
||||||
|
(tmp_path / "foo" / "bar").write_text("Bad file")
|
||||||
|
fileroot = str(tmp_path / "srv" / "salt")
|
||||||
|
badfile = str(tmp_path / "foo" / "bar")
|
||||||
|
opts = {
|
||||||
|
"fileserver_backend": ["roots"],
|
||||||
|
"extension_modules": "",
|
||||||
|
"optimization_order": [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
"file_roots": {
|
||||||
|
"base": [fileroot],
|
||||||
|
},
|
||||||
|
"file_ignore_regex": "",
|
||||||
|
"file_ignore_glob": "",
|
||||||
|
}
|
||||||
|
fs = salt.fileserver.Fileserver(opts)
|
||||||
|
ret = fs.find_file(
|
||||||
|
"salt://|..\\..\\..\\foo/bar",
|
||||||
|
"base",
|
||||||
|
)
|
||||||
|
assert ret == {"path": "", "rel": ""}
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_server_serve_url_escape(tmp_path):
|
||||||
|
(tmp_path / "srv").mkdir()
|
||||||
|
(tmp_path / "srv" / "salt").mkdir()
|
||||||
|
(tmp_path / "foo").mkdir()
|
||||||
|
(tmp_path / "foo" / "bar").write_text("Bad file")
|
||||||
|
fileroot = str(tmp_path / "srv" / "salt")
|
||||||
|
badfile = str(tmp_path / "foo" / "bar")
|
||||||
|
opts = {
|
||||||
|
"fileserver_backend": ["roots"],
|
||||||
|
"extension_modules": "",
|
||||||
|
"optimization_order": [
|
||||||
|
0,
|
||||||
|
],
|
||||||
|
"file_roots": {
|
||||||
|
"base": [fileroot],
|
||||||
|
},
|
||||||
|
"file_ignore_regex": "",
|
||||||
|
"file_ignore_glob": "",
|
||||||
|
"file_buffer_size": 2048,
|
||||||
|
}
|
||||||
|
fs = salt.fileserver.Fileserver(opts)
|
||||||
|
ret = fs.serve_file(
|
||||||
|
{
|
||||||
|
"path": "salt://|..\\..\\..\\foo/bar",
|
||||||
|
"saltenv": "base",
|
||||||
|
"loc": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert ret == {"data": "", "dest": ""}
|
|
@ -1021,3 +1021,35 @@ def test_key_dfn_wait(cluster_maintenance):
|
||||||
thread.join()
|
thread.join()
|
||||||
assert time.time() - start >= 5
|
assert time.time() - start >= 5
|
||||||
assert dfn.read_text() == "othermaster"
|
assert dfn.read_text() == "othermaster"
|
||||||
|
|
||||||
|
|
||||||
|
def test_syndic_return_cache_dir_creation(encrypted_requests):
|
||||||
|
"""master's cachedir for a syndic will be created by AESFuncs._syndic_return method"""
|
||||||
|
cachedir = pathlib.Path(encrypted_requests.opts["cachedir"])
|
||||||
|
assert not (cachedir / "syndics").exists()
|
||||||
|
encrypted_requests._syndic_return(
|
||||||
|
{
|
||||||
|
"id": "mamajama",
|
||||||
|
"jid": "",
|
||||||
|
"return": {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert (cachedir / "syndics").exists()
|
||||||
|
assert (cachedir / "syndics" / "mamajama").exists()
|
||||||
|
|
||||||
|
|
||||||
|
def test_syndic_return_cache_dir_creation_traversal(encrypted_requests):
|
||||||
|
"""
|
||||||
|
master's AESFuncs._syndic_return method cachdir creation is not vulnerable to a directory traversal
|
||||||
|
"""
|
||||||
|
cachedir = pathlib.Path(encrypted_requests.opts["cachedir"])
|
||||||
|
assert not (cachedir / "syndics").exists()
|
||||||
|
encrypted_requests._syndic_return(
|
||||||
|
{
|
||||||
|
"id": "../mamajama",
|
||||||
|
"jid": "",
|
||||||
|
"return": {},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert not (cachedir / "syndics").exists()
|
||||||
|
assert not (cachedir / "mamajama").exists()
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
"""
|
|
||||||
:codeauthor: Joao Mesquita <jmesquita@sangoma.com>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
import salt.utils.files
|
|
||||||
from salt import fileserver
|
|
||||||
from tests.support.helpers import with_tempdir
|
|
||||||
from tests.support.mixins import LoaderModuleMockMixin
|
|
||||||
from tests.support.unit import TestCase
|
|
||||||
|
|
||||||
|
|
||||||
class MapDiffTestCase(TestCase):
|
|
||||||
def test_diff_with_diffent_keys(self):
|
|
||||||
"""
|
|
||||||
Test that different maps are indeed reported different
|
|
||||||
"""
|
|
||||||
map1 = {"file1": 1234}
|
|
||||||
map2 = {"file2": 1234}
|
|
||||||
assert fileserver.diff_mtime_map(map1, map2) is True
|
|
||||||
|
|
||||||
def test_diff_with_diffent_values(self):
|
|
||||||
"""
|
|
||||||
Test that different maps are indeed reported different
|
|
||||||
"""
|
|
||||||
map1 = {"file1": 12345}
|
|
||||||
map2 = {"file1": 1234}
|
|
||||||
assert fileserver.diff_mtime_map(map1, map2) is True
|
|
||||||
|
|
||||||
|
|
||||||
class VCSBackendWhitelistCase(TestCase, LoaderModuleMockMixin):
|
|
||||||
def setup_loader_modules(self):
|
|
||||||
return {fileserver: {}}
|
|
||||||
|
|
||||||
def test_whitelist(self):
|
|
||||||
opts = {
|
|
||||||
"fileserver_backend": ["roots", "git", "s3fs", "hgfs", "svn"],
|
|
||||||
"extension_modules": "",
|
|
||||||
}
|
|
||||||
fs = fileserver.Fileserver(opts)
|
|
||||||
assert sorted(fs.servers.whitelist) == sorted(
|
|
||||||
["git", "gitfs", "hg", "hgfs", "svn", "svnfs", "roots", "s3fs"]
|
|
||||||
), fs.servers.whitelist
|
|
||||||
|
|
||||||
@with_tempdir()
|
|
||||||
def test_future_file_list_cache_file_ignored(self, cachedir):
|
|
||||||
opts = {
|
|
||||||
"fileserver_backend": ["roots"],
|
|
||||||
"cachedir": cachedir,
|
|
||||||
"extension_modules": "",
|
|
||||||
}
|
|
||||||
|
|
||||||
back_cachedir = os.path.join(cachedir, "file_lists/roots")
|
|
||||||
os.makedirs(os.path.join(back_cachedir))
|
|
||||||
|
|
||||||
# Touch a couple files
|
|
||||||
for filename in ("base.p", "foo.txt"):
|
|
||||||
with salt.utils.files.fopen(
|
|
||||||
os.path.join(back_cachedir, filename), "wb"
|
|
||||||
) as _f:
|
|
||||||
if filename == "base.p":
|
|
||||||
_f.write(b"\x80")
|
|
||||||
|
|
||||||
# Set modification time to file list cache file to 1 year in the future
|
|
||||||
now = datetime.datetime.utcnow()
|
|
||||||
future = now + datetime.timedelta(days=365)
|
|
||||||
mod_time = time.mktime(future.timetuple())
|
|
||||||
os.utime(os.path.join(back_cachedir, "base.p"), (mod_time, mod_time))
|
|
||||||
|
|
||||||
list_cache = os.path.join(back_cachedir, "base.p")
|
|
||||||
w_lock = os.path.join(back_cachedir, ".base.w")
|
|
||||||
ret = fileserver.check_file_list_cache(opts, "files", list_cache, w_lock)
|
|
||||||
assert (
|
|
||||||
ret[1] is True
|
|
||||||
), "Cache file list cache file is not refreshed when future modification time"
|
|
|
@ -1285,7 +1285,9 @@ def upload_coverage(ctx: Context, reports_path: pathlib.Path, commit_sha: str =
|
||||||
break
|
break
|
||||||
|
|
||||||
if current_attempt >= max_attempts:
|
if current_attempt >= max_attempts:
|
||||||
ctx.error(f"Failed to upload {fpath} to codecov")
|
ctx.error(f"Failed to upload {fpath} to codecov:")
|
||||||
|
ctx.console_stdout.print(stdout)
|
||||||
|
ctx.console.print(stderr)
|
||||||
ctx.exit(1)
|
ctx.exit(1)
|
||||||
|
|
||||||
ctx.warn(f"Waiting {sleep_time} seconds until next retry...")
|
ctx.warn(f"Waiting {sleep_time} seconds until next retry...")
|
||||||
|
|
|
@ -135,13 +135,13 @@ def download_onedir_artifact(
|
||||||
s3 = boto3.client("s3")
|
s3 = boto3.client("s3")
|
||||||
if platform == "darwin":
|
if platform == "darwin":
|
||||||
platform = "macos"
|
platform = "macos"
|
||||||
if arch == "arm64":
|
if arch == "aarch64":
|
||||||
arch = "aarch64"
|
arch = "arm64"
|
||||||
arch = arch.lower()
|
arch = arch.lower()
|
||||||
platform = platform.lower()
|
platform = platform.lower()
|
||||||
if platform in ("linux", "macos") and arch not in ("x86_64", "aarch64"):
|
if platform in ("linux", "macos") and arch not in ("x86_64", "arm64"):
|
||||||
ctx.error(
|
ctx.error(
|
||||||
f"The 'arch' value for {platform} must be one of: 'x86_64', 'aarch64', 'arm64'"
|
f"The 'arch' value for {platform} must be one of: 'x86_64', 'aarch64', 'aarch64'"
|
||||||
)
|
)
|
||||||
ctx.exit(1)
|
ctx.exit(1)
|
||||||
if platform == "windows" and arch not in ("x86", "amd64"):
|
if platform == "windows" and arch not in ("x86", "amd64"):
|
||||||
|
|
Loading…
Add table
Reference in a new issue