deb/control/apt/
sources_list.rs

1// {{{ Copyright (c) Paul R. Tagliamonte <paultag@debian.org>, 2024
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19// THE SOFTWARE. }}}
20
21#[cfg(feature = "serde")]
22use ::serde::{Deserialize, Serialize};
23
24use super::YesNoForce;
25use crate::control::{Architectures, SpaceDelimitedStrings};
26
27// TODO: check which fields are optional; add tests
28
29/// Information on where to fetch information regarding installable
30/// Debian files, and optionally, their corresponding source.
31#[derive(Clone, Debug, PartialEq)]
32#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))]
34pub struct SourcesList {
35    /// If not enabled, this source entry will be ignored.
36    pub enabled: Option<bool>,
37
38    /// If `deb` is present, this will be used to fetch `.deb` files from.
39    /// If `deb-src` is present, this will also be used to fetch `.dsc` files
40    /// and its manifested additional source files.
41    pub types: SpaceDelimitedStrings,
42
43    /// base of the Debian distribution, from which APT will find the
44    /// information it needs. suite can specify an exact path, in which case
45    /// the components must be omitted and suite must end with a slash (/).
46    /// This is useful for the case when only a particular sub-directory of the
47    /// archive denoted by the URI is of interest. If suite does not specify an
48    /// exact path, at least one component must be present.
49    #[cfg_attr(feature = "serde", serde(rename = "URIs"))]
50    pub uris: SpaceDelimitedStrings,
51
52    /// suite may also contain a variable, `$(ARCH)` which expands to the Debian
53    /// architecture (such as amd64 or armel) used on the system. This permits
54    /// architecture-independent sources.list files to be used. In general this
55    /// is only of interest when specifying an exact path; APT will
56    /// automatically generate a URI with the current architecture otherwise.
57    pub suites: SpaceDelimitedStrings,
58
59    /// Archive components to use (like `main`, `contrib`, `non-free`, etc).
60    pub components: SpaceDelimitedStrings,
61
62    /// Set which architectures information should be downloaded.
63    pub architectures: Option<Architectures>,
64
65    /// List ofe languages which language-specific information such as
66    /// translated package descriptions should be downloaded.
67    pub languages: Option<SpaceDelimitedStrings>,
68
69    /// Targets apt will try to acquire from this source. If not specified,
70    /// the default set is defined by the Acquire::IndexTargets configuration
71    /// scope (targets are specified by their name in the Created-By field).
72    pub targets: Option<SpaceDelimitedStrings>,
73
74    /// Use PDiffs to update old indexes instead of downloading the new
75    /// indexes entirely.
76    #[cfg_attr(feature = "serde", serde(rename = "PDiffs"))]
77    pub pdiffs: Option<bool>,
78
79    /// can have the value yes, no or force and controls if APT should try to
80    /// acquire indexes via a URI constructed from a hashsum of the expected
81    /// file instead of using the well-known stable filename of the index.
82    #[cfg_attr(feature = "serde", serde(rename = "By-Hash"))]
83    pub by_hash: Option<YesNoForce>,
84
85    /// Circumvent parts of `apt-secure(8)`. Don't do this casually.
86    #[cfg_attr(feature = "serde", serde(rename = "Allow-Insecure"))]
87    pub allow_insecure: Option<bool>,
88
89    /// Circumvent parts of `apt-secure(8)`. Don't do this casually.
90    #[cfg_attr(feature = "serde", serde(rename = "Allow-Weak"))]
91    pub allow_weak: Option<bool>,
92
93    /// Circumvent parts of `apt-secure(8)`. Don't do this casually.
94    #[cfg_attr(feature = "serde", serde(rename = "Allow-Downgrade-To-Insecure"))]
95    pub allow_downgrade_to_insecure: Option<bool>,
96
97    /// Set the source to trusted or not, even if it doesn't pass authentication
98    /// checks.
99    ///
100    ///
101    /// This disables parts of `apt-secure(8)`, and should therefore only be
102    /// used in a local and trusted context (if at all) as otherwise security
103    /// is breached. The value no does the opposite, causing the source to be
104    /// handled as untrusted even if the authentication checks passed
105    /// successfully.
106    pub trusted: Option<bool>,
107
108    /// require a repository to pass apt-secure(8) verification with a certain
109    /// set of keys rather than all trusted keys apt has configured.
110    ///
111    /// It is specified as a list of absolute paths to keyring files,
112    /// and fingerprints of keys to select from these keyrings. If no
113    /// fingerprint is specified all keys in the keyrings are selected. A
114    /// fingerprint will accept also all signatures by a subkey of this key,
115    /// if this isn't desired an exclamation mark (!) can be appended to the
116    /// fingerprint to disable this behaviour.
117    ///
118    /// The option may also be set directly to an embedded GPG public key
119    /// block.
120    #[cfg_attr(feature = "serde", serde(rename = "Signed-By"))]
121    pub signed_by: Option<String>,
122
123    /// yes/no value which controls if APT should try to detect replay attacks.
124    #[cfg_attr(feature = "serde", serde(rename = "Check-Valid-Until"))]
125    pub check_valid_until: Option<bool>,
126
127    /// lower the time period in seconds in which the data from this repository
128    /// is considered valid.
129    #[cfg_attr(feature = "serde", serde(rename = "Valid-Until-Min"))]
130    pub valid_until_min: Option<usize>,
131
132    /// raise the time period in seconds in which the data from this repository
133    /// is considered valid.
134    #[cfg_attr(feature = "serde", serde(rename = "Valid-Until-Max"))]
135    pub valid_until_max: Option<usize>,
136
137    /// consider the machine's time correct and hence perform time related
138    /// checks, such as verifying that a Release file is not from the future.
139    #[cfg_attr(feature = "serde", serde(rename = "Check-Date"))]
140    pub check_date: Option<bool>,
141
142    /// controls how far from the future a repository may be. Default to the
143    /// value of the configuration option Acquire::Max-FutureTime which is 10
144    /// seconds by default.
145    #[cfg_attr(feature = "serde", serde(rename = "Date-Max-Future"))]
146    pub date_max_future: Option<usize>,
147
148    /// path to the InRelease file, relative to the normal position of an
149    /// InRelease file.
150    #[cfg_attr(feature = "serde", serde(rename = "InRelease-Path"))]
151    pub inrelease_path: Option<String>,
152
153    /// allows selecting an earlier version of the archive from the snapshot
154    /// service.
155    pub snapshot: Option<String>,
156}
157
158#[cfg(test)]
159mod tests {
160    #[cfg(feature = "serde")]
161    use super::*;
162
163    #[cfg(feature = "serde")]
164    mod serde {
165        use super::*;
166        use crate::{architecture, control::de};
167
168        macro_rules! test_sources_list {
169            ($name:ident, $data:expr, |$parsed:ident| $block:tt) => {
170                #[test]
171                fn $name() {
172                    let $parsed = de::from_str::<SourcesList>($data).unwrap();
173                    $block
174                }
175            };
176        }
177
178        test_sources_list!(
179            apt_manpage_example_1,
180            "\
181Types: deb
182URIs: http://deb.debian.org/debian
183Suites: bookworm bookworm-updates
184Components: main contrib non-free non-free-firmware
185",
186            |sources| {
187                assert_eq!(&["deb"], &*sources.types);
188                assert_eq!(&["http://deb.debian.org/debian"], &*sources.uris);
189                assert_eq!(&["bookworm", "bookworm-updates"], &*sources.suites);
190                assert_eq!(
191                    &["main", "contrib", "non-free", "non-free-firmware"],
192                    &*sources.components
193                );
194            }
195        );
196
197        test_sources_list!(
198            apt_manpage_signed_by,
199            "\
200Types: deb
201URIs: https://deb.debian.org
202Suites: stable
203Components: main contrib non-free non-free-firmware
204Signed-By:
205 -----BEGIN PGP PUBLIC KEY BLOCK-----
206 .
207 mDMEYCQjIxYJKwYBBAHaRw8BAQdAD/P5Nvvnvk66SxBBHDbhRml9ORg1WV5CvzKY
208 CuMfoIS0BmFiY2RlZoiQBBMWCgA4FiEErCIG1VhKWMWo2yfAREZd5NfO31cFAmAk
209 IyMCGyMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQREZd5NfO31fbOwD6ArzS
210 dM0Dkd5h2Ujy1b6KcAaVW9FOa5UNfJ9FFBtjLQEBAJ7UyWD3dZzhvlaAwunsk7DG
211 3bHcln8DMpIJVXht78sL
212 =IE0r
213 -----END PGP PUBLIC KEY BLOCK-----
214",
215            |sources| {
216                assert!(
217                    sources
218                        .signed_by
219                        .unwrap()
220                        .trim()
221                        .starts_with("-----BEGIN PGP PUBLIC KEY BLOCK-----")
222                );
223            }
224        );
225
226        test_sources_list!(
227            apt_manpage_example_2,
228            "\
229Types: deb
230URIs: http://deb.debian.org/debian
231Suites: bookworm
232Components: main
233Architectures: amd64 armel
234",
235            |sources| {
236                assert_eq!(
237                    &[architecture::AMD64, architecture::ARMEL],
238                    &*sources.architectures.unwrap()
239                );
240            }
241        );
242
243        test_sources_list!(
244            apt_bool_one,
245            "\
246Types: deb
247URIs: http://deb.debian.org/debian
248Suites: bookworm
249Components: main
250Architectures: amd64 armel
251Allow-Insecure: yes
252",
253            |sources| {
254                assert!(sources.allow_insecure.unwrap());
255            }
256        );
257    }
258}
259
260// vim: foldmethod=marker