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