Skip to content
This repository was archived by the owner on Feb 7, 2026. It is now read-only.

Commit dfc2472

Browse files
committed
Add signature handling for manifests
- Implemented support for fetching, importing, and storing signature payloads during transaction creation. - Added the `Signature` struct to represent signature-related action data. - Updated `Manifest` to include and process `signatures` as part of its fields. - Enabled signature file imports with proper path resolution in `pkg6repo`.
1 parent 38baf16 commit dfc2472

3 files changed

Lines changed: 91 additions & 1 deletion

File tree

libips/src/actions/mod.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,35 @@ impl From<Action> for Transform {
790790
}
791791
}
792792

793+
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, Diff)]
794+
#[diff(attr(
795+
#[derive(Debug, PartialEq)]
796+
))]
797+
pub struct Signature {
798+
pub value: String,
799+
pub algorithm: String,
800+
pub chain: String,
801+
pub chash: String,
802+
pub version: String,
803+
}
804+
805+
impl From<Action> for Signature {
806+
fn from(act: Action) -> Self {
807+
let mut sig = Signature::default();
808+
sig.value = act.payload_string;
809+
for prop in act.properties {
810+
match prop.key.as_str() {
811+
"algorithm" => sig.algorithm = prop.value,
812+
"chain" => sig.chain = prop.value,
813+
"chash" => sig.chash = prop.value,
814+
"version" => sig.version = prop.value,
815+
_ => {}
816+
}
817+
}
818+
sig
819+
}
820+
}
821+
793822
#[derive(Hash, Eq, PartialEq, Debug, Default, Clone, Deserialize, Serialize, Diff)]
794823
#[diff(attr(
795824
#[derive(Debug, PartialEq)]
@@ -827,6 +856,8 @@ pub struct Manifest {
827856
pub legacies: Vec<Legacy>,
828857
#[serde(skip_serializing_if = "Vec::is_empty", default)]
829858
pub transforms: Vec<Transform>,
859+
#[serde(skip_serializing_if = "Vec::is_empty", default)]
860+
pub signatures: Vec<Signature>,
830861
}
831862

832863
impl Manifest {
@@ -843,6 +874,7 @@ impl Manifest {
843874
drivers: Vec::new(),
844875
legacies: Vec::new(),
845876
transforms: Vec::new(),
877+
signatures: Vec::new(),
846878
}
847879
}
848880

@@ -886,7 +918,7 @@ impl Manifest {
886918
self.transforms.push(act.into());
887919
}
888920
ActionKind::Signature => {
889-
debug!("signature action encountered, skipping for now");
921+
self.signatures.push(act.into());
890922
}
891923
ActionKind::Unknown { action } => {
892924
debug!("action {:?} not known, skipping", action);

libips/src/recv.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,23 @@ impl<'a, S: ReadableRepository + Sync> PackageReceiver<'a, S> {
266266
txn.add_file((*file).clone(), &temp_file_path)?;
267267
}
268268

269+
// Fetch signature payloads
270+
for sig in &manifest.signatures {
271+
if sig.value.is_empty() {
272+
continue;
273+
}
274+
275+
let digest = &sig.value;
276+
let temp_file_path = temp_dir.path().join(format!("sig-{}", digest));
277+
debug!("Fetching signature payload {} to {}", digest, temp_file_path.display());
278+
279+
self.source.fetch_payload(publisher, digest, &temp_file_path)?;
280+
281+
let mut sig_file_action = crate::actions::File::default();
282+
sig_file_action.path = format!("signature-{}", digest);
283+
txn.add_file(sig_file_action, &temp_file_path)?;
284+
}
285+
269286
txn.update_manifest(manifest.clone());
270287
txn.commit()?;
271288

pkg6repo/src/pkg5_import.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,47 @@ impl Pkg5Importer {
554554
}
555555
}
556556

557+
// Import signature files
558+
for signature in &manifest.signatures {
559+
if signature.value.is_empty() {
560+
continue;
561+
}
562+
563+
let hash = &signature.value;
564+
// Determine the file path in the source repository
565+
let first_two = &hash[0..2];
566+
let next_two = &hash[2..4];
567+
let file_path_new = file_dir.join(first_two).join(next_two).join(hash);
568+
let file_path_old = file_dir.join(first_two).join(hash);
569+
570+
let file_path = if file_path_new.exists() {
571+
file_path_new
572+
} else if file_path_old.exists() {
573+
file_path_old
574+
} else {
575+
warn!(
576+
"Signature file not found in source repository: {}",
577+
hash
578+
);
579+
continue;
580+
};
581+
582+
// Use a unique name for the signature file in the proto dir
583+
let proto_sig_path = proto_dir.join(format!("signature-{}", hash));
584+
if let Some(parent) = proto_sig_path.parent() {
585+
fs::create_dir_all(parent).map_err(|e| Pkg6RepoError::IoError(e))?;
586+
}
587+
588+
fs::copy(&file_path, &proto_sig_path).map_err(|e| Pkg6RepoError::IoError(e))?;
589+
590+
// We need a FileAction to add it to the transaction
591+
// Even though it's a signature, FileBackend uses add_file to store payloads
592+
let mut sig_file_action = libips::actions::File::default();
593+
sig_file_action.path = format!("signature-{}", hash);
594+
// transaction.add_file will calculate the hash and store it in the repo's file dir
595+
transaction.add_file(sig_file_action, &proto_sig_path)?;
596+
}
597+
557598
// Update the manifest in the transaction
558599
transaction.update_manifest(manifest);
559600

0 commit comments

Comments
 (0)