Struct apple_codesign::CodeResources
source · pub struct CodeResources { /* private fields */ }Expand description
Represents a _CodeSignature/CodeResources XML plist.
This file/type represents a collection of file-based resources whose content is digested and captured in this file.
Implementations§
source§impl CodeResources
impl CodeResources
sourcepub fn from_xml(xml: &[u8]) -> Result<Self, AppleCodesignError>
pub fn from_xml(xml: &[u8]) -> Result<Self, AppleCodesignError>
Construct an instance by parsing an XML plist.
sourcepub fn to_writer_xml(&self, writer: impl Write) -> Result<(), AppleCodesignError>
pub fn to_writer_xml(&self, writer: impl Write) -> Result<(), AppleCodesignError>
Serialize an instance to XML.
sourcepub fn add_rule(&mut self, rule: CodeResourcesRule)
pub fn add_rule(&mut self, rule: CodeResourcesRule)
Add a rule to this instance in the <rules> section.
sourcepub fn add_rule2(&mut self, rule: CodeResourcesRule)
pub fn add_rule2(&mut self, rule: CodeResourcesRule)
Add a rule to this instance in the <rules2> section.
sourcepub fn seal_regular_file(
&mut self,
files_flavor: FilesFlavor,
path: impl ToString,
content: impl AsRef<[u8]>,
optional: bool
) -> Result<(), AppleCodesignError>
pub fn seal_regular_file(
&mut self,
files_flavor: FilesFlavor,
path: impl ToString,
content: impl AsRef<[u8]>,
optional: bool
) -> Result<(), AppleCodesignError>
Seal a regular file.
This will digest the content specified and record that digest in the files or files2 list.
To seal a symlink, call CodeResources::seal_symlink instead. If the file is a Mach-O file, call CodeResources::seal_macho instead.
Examples found in repository?
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
fn process_file_rules2(
&mut self,
file: &DirectoryBundleFile,
file_handler: &dyn BundleFileHandler,
) -> Result<(), AppleCodesignError> {
match Self::evaluate_rules(
&self.rules2,
file.relative_path(),
file.symlink_target()
.map_err(AppleCodesignError::DirectoryBundle)?,
)? {
RulesEvaluation::Exclude => {
// Excluded files are hard ignored. These files are likely handled out-of-band
// from this builder.
Ok(())
}
RulesEvaluation::Omit => {
// Omitted files aren't sealed. But they are installed.
file_handler.install_file(file)
}
RulesEvaluation::NoRule => {
// No rule match is assumed to mean full ignore.
Ok(())
}
RulesEvaluation::SealSymlink(relative_path, target) => {
info!("sealing symlink {} -> {}", relative_path, target);
self.resources.seal_symlink(relative_path, target);
file_handler.install_file(file)
}
RulesEvaluation::SealNested(relative_path, optional) => {
// The assumption that a nested match means Mach-O may not be correct.
info!("sealing Mach-O file {}", relative_path);
let macho_info = file_handler.sign_and_install_macho(file)?;
self.resources
.seal_macho(relative_path, &macho_info, optional)
}
RulesEvaluation::SealRegularFile(relative_path, optional) => {
info!("sealing regular file {}", relative_path);
let data = std::fs::read(file.absolute_path())?;
let flavor = if self.digests.contains(&DigestType::Sha1) {
FilesFlavor::Rules2WithSha1
} else {
FilesFlavor::Rules2
};
self.resources
.seal_regular_file(flavor, relative_path, data, optional)?;
file_handler.install_file(file)
}
}
}
/// Process the `<rules>` set for a given file.
///
/// Since `<rules2>` handling actually does the file installs, the only role of this
/// handler is to record the SHA-1 seals in `<files>`. Keep in mind that `<files>` can't
/// handle symlinks or nested Mach-O binaries. So we only care about regular files here.
fn process_file_rules(&mut self, file: &DirectoryBundleFile) -> Result<(), AppleCodesignError> {
match Self::evaluate_rules(
&self.rules,
file.relative_path(),
file.symlink_target()
.map_err(AppleCodesignError::DirectoryBundle)?,
)? {
RulesEvaluation::Exclude
| RulesEvaluation::Omit
| RulesEvaluation::NoRule
| RulesEvaluation::SealSymlink(..)
| RulesEvaluation::SealNested(..) => Ok(()),
RulesEvaluation::SealRegularFile(relative_path, optional) => {
let data = std::fs::read(file.absolute_path())?;
self.resources
.seal_regular_file(FilesFlavor::Rules, relative_path, data, optional)
}
}
}sourcepub fn seal_symlink(&mut self, path: impl ToString, target: impl ToString)
pub fn seal_symlink(&mut self, path: impl ToString, target: impl ToString)
Seal a symlink file.
path is the path of the symlink and target is the path it points to.
Examples found in repository?
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250
fn process_file_rules2(
&mut self,
file: &DirectoryBundleFile,
file_handler: &dyn BundleFileHandler,
) -> Result<(), AppleCodesignError> {
match Self::evaluate_rules(
&self.rules2,
file.relative_path(),
file.symlink_target()
.map_err(AppleCodesignError::DirectoryBundle)?,
)? {
RulesEvaluation::Exclude => {
// Excluded files are hard ignored. These files are likely handled out-of-band
// from this builder.
Ok(())
}
RulesEvaluation::Omit => {
// Omitted files aren't sealed. But they are installed.
file_handler.install_file(file)
}
RulesEvaluation::NoRule => {
// No rule match is assumed to mean full ignore.
Ok(())
}
RulesEvaluation::SealSymlink(relative_path, target) => {
info!("sealing symlink {} -> {}", relative_path, target);
self.resources.seal_symlink(relative_path, target);
file_handler.install_file(file)
}
RulesEvaluation::SealNested(relative_path, optional) => {
// The assumption that a nested match means Mach-O may not be correct.
info!("sealing Mach-O file {}", relative_path);
let macho_info = file_handler.sign_and_install_macho(file)?;
self.resources
.seal_macho(relative_path, &macho_info, optional)
}
RulesEvaluation::SealRegularFile(relative_path, optional) => {
info!("sealing regular file {}", relative_path);
let data = std::fs::read(file.absolute_path())?;
let flavor = if self.digests.contains(&DigestType::Sha1) {
FilesFlavor::Rules2WithSha1
} else {
FilesFlavor::Rules2
};
self.resources
.seal_regular_file(flavor, relative_path, data, optional)?;
file_handler.install_file(file)
}
}
}sourcepub fn seal_macho(
&mut self,
path: impl ToString,
info: &SignedMachOInfo,
optional: bool
) -> Result<(), AppleCodesignError>
pub fn seal_macho(
&mut self,
path: impl ToString,
info: &SignedMachOInfo,
optional: bool
) -> Result<(), AppleCodesignError>
Record metadata of a previously signed Mach-O binary.
If sealing a fat/universal binary, pass in metadata for the first Mach-O within in.
Examples found in repository?
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
fn process_file_rules2(
&mut self,
file: &DirectoryBundleFile,
file_handler: &dyn BundleFileHandler,
) -> Result<(), AppleCodesignError> {
match Self::evaluate_rules(
&self.rules2,
file.relative_path(),
file.symlink_target()
.map_err(AppleCodesignError::DirectoryBundle)?,
)? {
RulesEvaluation::Exclude => {
// Excluded files are hard ignored. These files are likely handled out-of-band
// from this builder.
Ok(())
}
RulesEvaluation::Omit => {
// Omitted files aren't sealed. But they are installed.
file_handler.install_file(file)
}
RulesEvaluation::NoRule => {
// No rule match is assumed to mean full ignore.
Ok(())
}
RulesEvaluation::SealSymlink(relative_path, target) => {
info!("sealing symlink {} -> {}", relative_path, target);
self.resources.seal_symlink(relative_path, target);
file_handler.install_file(file)
}
RulesEvaluation::SealNested(relative_path, optional) => {
// The assumption that a nested match means Mach-O may not be correct.
info!("sealing Mach-O file {}", relative_path);
let macho_info = file_handler.sign_and_install_macho(file)?;
self.resources
.seal_macho(relative_path, &macho_info, optional)
}
RulesEvaluation::SealRegularFile(relative_path, optional) => {
info!("sealing regular file {}", relative_path);
let data = std::fs::read(file.absolute_path())?;
let flavor = if self.digests.contains(&DigestType::Sha1) {
FilesFlavor::Rules2WithSha1
} else {
FilesFlavor::Rules2
};
self.resources
.seal_regular_file(flavor, relative_path, data, optional)?;
file_handler.install_file(file)
}
}
}
/// Process the `<rules>` set for a given file.
///
/// Since `<rules2>` handling actually does the file installs, the only role of this
/// handler is to record the SHA-1 seals in `<files>`. Keep in mind that `<files>` can't
/// handle symlinks or nested Mach-O binaries. So we only care about regular files here.
fn process_file_rules(&mut self, file: &DirectoryBundleFile) -> Result<(), AppleCodesignError> {
match Self::evaluate_rules(
&self.rules,
file.relative_path(),
file.symlink_target()
.map_err(AppleCodesignError::DirectoryBundle)?,
)? {
RulesEvaluation::Exclude
| RulesEvaluation::Omit
| RulesEvaluation::NoRule
| RulesEvaluation::SealSymlink(..)
| RulesEvaluation::SealNested(..) => Ok(()),
RulesEvaluation::SealRegularFile(relative_path, optional) => {
let data = std::fs::read(file.absolute_path())?;
self.resources
.seal_regular_file(FilesFlavor::Rules, relative_path, data, optional)
}
}
}
/// Process a file for resource handling.
///
/// This determines whether a file is relevant for inclusion in the CodeResources
/// file and takes actions to process it, if necessary.
pub fn process_file(
&mut self,
file: &DirectoryBundleFile,
file_handler: &dyn BundleFileHandler,
) -> Result<(), AppleCodesignError> {
self.process_file_rules2(file, file_handler)?;
self.process_file_rules(file)
}
/// Process a nested bundle for inclusion in resource handling.
///
/// This will attempt to seal the main digest of the bundle into this resources file.
pub fn process_nested_bundle(
&mut self,
relative_path: &str,
bundle: &DirectoryBundle,
) -> Result<(), AppleCodesignError> {
let main_exe = match bundle
.files(false)
.map_err(AppleCodesignError::DirectoryBundle)?
.into_iter()
.find(|file| matches!(file.is_main_executable(), Ok(true)))
{
Some(path) => path,
None => {
warn!(
"nested bundle at {} does not have main executable; nothing to seal",
relative_path
);
return Ok(());
}
};
let (relative_path, optional) =
match Self::evaluate_rules(&self.rules2, relative_path, None)? {
RulesEvaluation::SealRegularFile(relative_path, optional) => {
(relative_path, optional)
}
RulesEvaluation::SealNested(relative_path, optional) => (relative_path, optional),
RulesEvaluation::Exclude => {
info!(
"excluding signing nested bundle {} because of matched resources rule",
relative_path
);
return Ok(());
}
res => {
warn!(
"unexpected resource rules evaluation result for nested bundle {}: {:?}",
relative_path, res
);
return Err(AppleCodesignError::BundleUnexpectedResourceRuleResult);
}
};
let macho_data = std::fs::read(main_exe.absolute_path())?;
let macho_info = SignedMachOInfo::parse_data(&macho_data)?;
info!("sealing nested bundle at {}", relative_path);
self.resources
.seal_macho(relative_path, &macho_info, optional)?;
Ok(())
}Trait Implementations§
source§impl Clone for CodeResources
impl Clone for CodeResources
source§fn clone(&self) -> CodeResources
fn clone(&self) -> CodeResources
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moresource§impl Debug for CodeResources
impl Debug for CodeResources
source§impl Default for CodeResources
impl Default for CodeResources
source§fn default() -> CodeResources
fn default() -> CodeResources
source§impl From<&CodeResources> for Value
impl From<&CodeResources> for Value
source§fn from(cr: &CodeResources) -> Self
fn from(cr: &CodeResources) -> Self
source§impl PartialEq<CodeResources> for CodeResources
impl PartialEq<CodeResources> for CodeResources
source§fn eq(&self, other: &CodeResources) -> bool
fn eq(&self, other: &CodeResources) -> bool
self and other values to be equal, and is used
by ==.impl StructuralPartialEq for CodeResources
Auto Trait Implementations§
impl RefUnwindSafe for CodeResources
impl Send for CodeResources
impl Sync for CodeResources
impl Unpin for CodeResources
impl UnwindSafe for CodeResources
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
self, then passes self.as_mut() into the pipe
function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
.tap_ref_mut() only in debug builds, and is erased in release
builds.