Struct apple_codesign::FileEntity
source · pub struct FileEntity {
pub path: PathBuf,
pub file_size: Option<u64>,
pub file_sha256: Option<String>,
pub symlink_target: Option<PathBuf>,
pub sub_path: Option<String>,
pub entity: SignatureEntity,
}
Fields§
§path: PathBuf
§file_size: Option<u64>
§file_sha256: Option<String>
§symlink_target: Option<PathBuf>
§sub_path: Option<String>
§entity: SignatureEntity
Implementations§
source§impl FileEntity
impl FileEntity
sourcepub fn from_path(
path: &Path,
report_path: Option<&Path>
) -> Result<Self, AppleCodesignError>
pub fn from_path(
path: &Path,
report_path: Option<&Path>
) -> Result<Self, AppleCodesignError>
Construct an instance from a Path.
Examples found in repository?
src/reader.rs (line 839)
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
pub fn entities(&self) -> Result<Vec<FileEntity>, AppleCodesignError> {
match self {
Self::Dmg(path, dmg) => {
let mut entity = FileEntity::from_path(path, None)?;
entity.entity = SignatureEntity::Dmg(Self::resolve_dmg_entity(dmg)?);
Ok(vec![entity])
}
Self::MachO(path, data) => Self::resolve_macho_entities_from_data(path, data, None),
Self::Bundle(bundle) => Self::resolve_bundle_entities(bundle),
Self::FlatPackage(path) => Self::resolve_flat_package_entities(path),
}
}
fn resolve_dmg_entity(dmg: &DmgReader) -> Result<DmgEntity, AppleCodesignError> {
let signature = if let Some(sig) = dmg.embedded_signature()? {
Some(sig.try_into()?)
} else {
None
};
Ok(DmgEntity {
code_signature_offset: dmg.koly().code_signature_offset,
code_signature_size: dmg.koly().code_signature_size,
signature,
})
}
fn resolve_macho_entities_from_data(
path: &Path,
data: &[u8],
report_path: Option<&Path>,
) -> Result<Vec<FileEntity>, AppleCodesignError> {
let mut entities = vec![];
let entity = FileEntity::from_path(path, report_path)?;
for macho in MachFile::parse(data)?.into_iter() {
let mut entity = entity.clone();
if let Some(index) = macho.index {
entity.sub_path = Some(format!("macho-index:{index}"));
}
entity.entity = SignatureEntity::MachO(Self::resolve_macho_entity(macho)?);
entities.push(entity);
}
Ok(entities)
}
fn resolve_macho_entity(macho: MachOBinary) -> Result<MachOEntity, AppleCodesignError> {
let mut entity = MachOEntity::default();
if let Some(sig) = macho.find_signature_data()? {
entity.linkedit_segment_file_start_offset = Some(sig.linkedit_segment_start_offset);
entity.linkedit_segment_file_end_offset = Some(sig.linkedit_segment_end_offset);
entity.signature_file_start_offset = Some(sig.linkedit_signature_start_offset);
entity.signature_file_end_offset = Some(sig.linkedit_signature_end_offset);
entity.signature_linkedit_start_offset = Some(sig.signature_start_offset);
entity.signature_linkedit_end_offset = Some(sig.signature_end_offset);
}
if let Some(sig) = macho.code_signature()? {
entity.signature = Some(sig.try_into()?);
}
Ok(entity)
}
fn resolve_bundle_entities(
bundle: &DirectoryBundle,
) -> Result<Vec<FileEntity>, AppleCodesignError> {
let mut entities = vec![];
for file in bundle
.files(true)
.map_err(AppleCodesignError::DirectoryBundle)?
{
entities.extend(
Self::resolve_bundle_file_entity(bundle.root_dir().to_path_buf(), file)?
.into_iter(),
);
}
Ok(entities)
}
fn resolve_bundle_file_entity(
base_path: PathBuf,
file: DirectoryBundleFile,
) -> Result<Vec<FileEntity>, AppleCodesignError> {
let main_relative_path = match file.absolute_path().strip_prefix(&base_path) {
Ok(path) => path.to_path_buf(),
Err(_) => file.absolute_path().to_path_buf(),
};
let mut entities = vec![];
let mut default_entity =
FileEntity::from_path(file.absolute_path(), Some(&main_relative_path))?;
let file_name = file
.absolute_path()
.file_name()
.expect("path should have file name")
.to_string_lossy();
let parent_dir = file
.absolute_path()
.parent()
.expect("path should have parent directory");
// There may be bugs in the code identifying the role of files in bundles.
// So rely on our own heuristics to detect and report on the file type.
if default_entity.symlink_target.is_some() {
entities.push(default_entity);
} else if parent_dir.ends_with("_CodeSignature") {
if file_name == "CodeResources" {
let data = std::fs::read(file.absolute_path())?;
default_entity.entity =
SignatureEntity::BundleCodeSignatureFile(CodeSignatureFile::ResourcesXml(
String::from_utf8_lossy(&data)
.split('\n')
.map(|x| x.replace('\t', " "))
.collect::<Vec<_>>(),
));
entities.push(default_entity);
} else {
default_entity.entity =
SignatureEntity::BundleCodeSignatureFile(CodeSignatureFile::Other);
entities.push(default_entity);
}
} else if file_name == "CodeResources" {
default_entity.entity =
SignatureEntity::BundleCodeSignatureFile(CodeSignatureFile::NotarizationTicket);
entities.push(default_entity);
} else {
let data = std::fs::read(file.absolute_path())?;
match Self::resolve_macho_entities_from_data(
file.absolute_path(),
&data,
Some(&main_relative_path),
) {
Ok(extra) => {
entities.extend(extra);
}
Err(_) => {
// Just some extra file.
entities.push(default_entity);
}
}
}
Ok(entities)
}
fn resolve_flat_package_entities(path: &Path) -> Result<Vec<FileEntity>, AppleCodesignError> {
let mut xar = XarReader::new(File::open(path)?)?;
let default_entity = FileEntity::from_path(path, None)?;
let mut entities = vec![];
let mut entity = default_entity.clone();
entity.sub_path = Some("toc".to_string());
entity.entity =
SignatureEntity::XarTableOfContents(XarTableOfContents::from_xar(&mut xar)?);
entities.push(entity);
// Now emit entries for all files in table of contents.
for (name, file) in xar.files()? {
let mut entity = default_entity.clone();
entity.sub_path = Some(name);
entity.entity = SignatureEntity::XarMember(XarFile::try_from(&file)?);
entities.push(entity);
}
Ok(entities)
}
Trait Implementations§
source§impl Clone for FileEntity
impl Clone for FileEntity
source§fn clone(&self) -> FileEntity
fn clone(&self) -> FileEntity
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl Debug for FileEntity
impl Debug for FileEntity
Auto Trait Implementations§
impl RefUnwindSafe for FileEntity
impl Send for FileEntity
impl Sync for FileEntity
impl Unpin for FileEntity
impl UnwindSafe for FileEntity
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Causes
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,
Formats each item in a sequence. Read more
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,
Pipes by value. This is generally the method you want to use. Read more
§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,
Borrows
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,
Mutably borrows
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,
Borrows
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,
Mutably borrows
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,
Immutable access to the
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,
Mutable access to the
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,
Immutable access to the
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,
Mutable access to the
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,
Immutable access to the
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,
Mutable access to the
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
Calls
.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
Calls
.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,
Calls
.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,
Calls
.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,
Calls
.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,
Calls
.tap_ref_mut()
only in debug builds, and is erased in release
builds.