Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing #40: Support KeyValue #43

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
17af462
fixed most clippy warnings
mutlusun Jun 20, 2020
571c95b
remove invalid rustfmt arguments
mutlusun Jun 21, 2020
0d2022e
move to rust 2018 edition
mutlusun Jun 21, 2020
b001a0f
remove comment
mutlusun Jul 4, 2020
484c1d1
Merge pull request #1 from pajowu/master
mutlusun Jul 14, 2020
ccd34cf
Merge branch 'master' of https://github.com/pajowu/signal-backup-decode
mutlusun Feb 23, 2021
43f2fdf
more robust read of password command
mutlusun Feb 26, 2021
5915642
update dependencies
mutlusun Feb 26, 2021
12b3846
update README and add github actions CI
mutlusun Mar 4, 2021
455cbe6
corret name in rust CI
mutlusun Mar 4, 2021
3370ccf
use build instead of test in rust CI
mutlusun Mar 4, 2021
ae4c476
mention packages to install in README file
mutlusun Mar 4, 2021
8adb708
check password length
mutlusun Mar 4, 2021
cecfa62
clarify rust installation
mutlusun Mar 4, 2021
7e73d69
Merge branch 'master' of https://github.com/pajowu/signal-backup-decode
mutlusun Mar 4, 2021
f8426c1
Merge branch 'master' of https://github.com/pajowu/signal-backup-decode
mutlusun Mar 25, 2021
e1fb0ba
add output of keyvalue type
mutlusun Mar 25, 2021
5872151
create frame: remove option and return result type
mutlusun Mar 25, 2021
70d9a58
fix naming of avatar files
mutlusun Mar 25, 2021
a8d6ee3
[output_raw] remove inmemory bool as it is not necessary
mutlusun Mar 26, 2021
994a888
simplify frame creation
mutlusun Mar 26, 2021
f544838
revert to old frame/protobuf handling
mutlusun May 7, 2021
2c94cd8
extend rust CI and fix clippy warnings
mutlusun May 7, 2021
027bd1f
update protobuf to fix error in latest rust version
mutlusun May 7, 2021
fb34b5d
revert CI test to not check protobuf compilation
mutlusun May 7, 2021
6e3440f
revert also clippy lints to not check for protobuf
mutlusun May 7, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ jobs:
toolchain: stable

- name: Build against current compiler
run: cargo build --verbose
run: cargo build
- name: Run tests against current compiler
run: cargo test --verbose
run: cargo test --no-fail-fast
- name: Check if rust code is correctly formatted
run: cargo fmt -- --check
- name: Check against clippy lints
run: cargo clippy -- -D warnings

build_and_test_1_41:
runs-on: ubuntu-latest
steps:
Expand Down
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository = "https://github.com/pajowu/signal-backup-decode"
edition = "2018"

[dependencies]
protobuf = "=2.22"
protobuf = "=2.22.1"
byteorder = "^1"
rust-ini = "^0.16"
clap = "^2.33"
Expand All @@ -31,7 +31,7 @@ chrono = { version = "^0.4", features = ["serde"] }
openssl = "^0.10"

[build-dependencies]
protoc-rust = {version = "^2.22", optional = true}
protoc-rust = {version = "^2.22.1", optional = true}

[features]
default = []
Expand Down
6 changes: 3 additions & 3 deletions src/Backups.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// This file is generated by rust-protobuf 2.22.0. Do not edit
// This file is generated by rust-protobuf 2.22.1. Do not edit
// @generated

// https://github.com/rust-lang/rust-clippy/issues/702
#![allow(unknown_lints)]
#![allow(clippy::all)]

#![allow(unused_attributes)]
#![rustfmt::skip]
#![cfg_attr(rustfmt, rustfmt::skip)]

#![allow(box_pointers)]
#![allow(dead_code)]
Expand All @@ -21,7 +21,7 @@

/// Generated files are compatible only with the same version
/// of protobuf runtime.
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_0;
// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_22_1;

#[derive(PartialEq,Clone,Default)]
pub struct SqlStatement {
Expand Down
2 changes: 1 addition & 1 deletion src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl Config {
unreachable!()
}
};
password.retain(|c| c >= '0' && c <= '9');
password.retain(|c| ('0'..='9').contains(&c));
let password = password.as_bytes().to_vec();
if password.len() != 30 {
return Err(anyhow!(
Expand Down
1 change: 0 additions & 1 deletion src/decrypter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use hmac::crypto_mac::Mac;
use hmac::crypto_mac::NewMac;
use openssl;
use sha2::Digest;
use subtle::ConstantTimeEq;

Expand Down
181 changes: 122 additions & 59 deletions src/frame.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::anyhow;
use anyhow::Context;
use std::convert::TryInto;

Expand Down Expand Up @@ -35,35 +36,53 @@ pub enum Frame {
data: Option<Vec<u8>>,
},
KeyValue {
key_value: crate::Backups::KeyValue
// optional string key = 1;
// optional bytes blobValue = 2;
// optional bool booleanValue = 3;
// optional float floatValue = 4;
// optional int32 integerValue = 5;
// optional int64 longValue = 6;
// optional string stringValue = 7;
}
key: String,
value: KeyValueContent,
},
}

#[derive(Debug)]
pub enum KeyValueContent {
Blob(Vec<u8>),
Bool(bool),
Float(f32),
Int(i64),
String(String),
}

impl Frame {
pub fn new(frame: &mut crate::Backups::BackupFrame) -> Self {
let mut fields_count = 0;
let mut ret: Option<Self> = None;
/// Creates a new frame from protobuf
pub fn new(frame: &mut crate::Backups::BackupFrame) -> Result<Self, anyhow::Error> {
// The field count and return value are necessary to check against unknown protobuf field
// types. Unknown field types might not be detected, thus `field_count` stays at zero.
// Sometimes they result in reading two different known field types, thus `field_count`
// gets increased to two.
//
// See: https://github.com/pajowu/signal-backup-decode/pull/43 for a discussion on this.
let mut field_count = 0;
let mut ret = Self::End;

if frame.has_header() {
fields_count += 1;
// increase field count
field_count += 1;

// get header
let mut header = frame.take_header();
ret = Some(Self::Header {

// return header
ret = Self::Header {
salt: header.take_salt(),
iv: header.take_iv(),
});
};
};
}

if frame.has_statement() {
fields_count += 1;
// increase field count
field_count += 1;

// build statement
let mut statement = frame.take_statement();
ret = Some(Self::Statement {
ret = Self::Statement {
statement: statement.take_statement(),
parameter: {
let mut params: Vec<rusqlite::types::Value> = Vec::new();
Expand All @@ -84,75 +103,119 @@ impl Frame {
}
params
},
});
};
};
}

if frame.has_preference() {
fields_count += 1;
ret = Some(Self::Preference {
// increase field count
field_count += 1;

// return preference
ret = Self::Preference {
preference: frame.take_preference(),
});
};
};
}

if frame.has_attachment() {
fields_count += 1;
// increase field count
field_count += 1;

// get attachment
let attachment = frame.take_attachment();
ret = Some(Self::Attachment {

// return attachment
ret = Self::Attachment {
data_length: attachment.get_length().try_into().unwrap(),
id: attachment.get_attachmentId(),
row: attachment.get_rowId(),
data: None,
});
};
};
}

if frame.has_version() {
fields_count += 1;
ret = Some(Self::Version {
// increase field count
field_count += 1;

// return version
ret = Self::Version {
version: frame.get_version().get_version(),
});
};
}
}

if frame.has_end() {
fields_count += 1;
ret = Some(Self::End);
};
// increase field count
field_count += 1;

ret = Self::End;
}

if frame.has_avatar() {
fields_count += 1;
// increase field count
field_count += 1;

// take avatar
let mut avatar = frame.take_avatar();
ret = Some(Self::Avatar {

// return avatar
ret = Self::Avatar {
data_length: avatar.get_length().try_into().unwrap(),
name: avatar.take_name(),
data: None,
});
};
};
}

if frame.has_sticker() {
fields_count += 1;
// increase field count
field_count += 1;

// take sticker
let sticker = frame.take_sticker();
ret = Some(Self::Sticker {

// return sticker
ret = Self::Sticker {
data_length: sticker.get_length().try_into().unwrap(),
row: sticker.get_rowId(),
data: None,
});
};
};
}

if frame.has_keyValue() {
fields_count += 1;
let key_value = frame.take_keyValue();
ret = Some(Self::KeyValue {
key_value
});
};

if fields_count != 1 {
panic!(
"Frame with an unsupported number of fields found, please report to author: {:?}",
frame
);
};
// increase field count
field_count += 1;

ret.unwrap()
// get keyvalue
let mut keyvalue = frame.take_keyValue();
let value = if keyvalue.has_blobValue() {
KeyValueContent::Blob(keyvalue.take_blobValue())
} else if keyvalue.has_booleanValue() {
KeyValueContent::Bool(keyvalue.get_booleanValue())
} else if keyvalue.has_floatValue() {
KeyValueContent::Float(keyvalue.get_floatValue())
} else if keyvalue.has_integerValue() {
KeyValueContent::Int(keyvalue.get_integerValue().into())
} else if keyvalue.has_longValue() {
KeyValueContent::Int(keyvalue.get_longValue())
} else if keyvalue.has_stringValue() {
KeyValueContent::String(keyvalue.take_stringValue())
} else {
unreachable!()
};

// return keyvalue
ret = Self::KeyValue {
key: keyvalue.take_key(),
value,
};
}

if field_count != 1 {
Err(anyhow!(
mutlusun marked this conversation as resolved.
Show resolved Hide resolved
"Frame with an unsupported field found, please report to author: {:?}",
frame
))
} else {
Ok(ret)
}
}

pub fn set_data(&mut self, data_add: Vec<u8>) {
Expand Down Expand Up @@ -183,7 +246,7 @@ impl std::fmt::Display for Frame {
Self::Statement { .. } => write!(f, "Statement"),
Self::Version { version } => write!(f, "Version ({})", version),
Self::End => write!(f, "End"),
Self::KeyValue { .. } => write!(f, "KeyValue"),
Self::KeyValue { key, value } => write!(f, "KeyValue: {} = {:?}", key, value),
}
}
}
Expand All @@ -194,6 +257,6 @@ impl std::convert::TryFrom<Vec<u8>> for Frame {
fn try_from(data: Vec<u8>) -> Result<Self, Self::Error> {
let mut frame = protobuf::Message::parse_from_bytes(&data)
.with_context(|| format!("Could not parse frame from {:02X?}", &data))?;
Ok(Self::new(&mut frame))
Self::new(&mut frame)
}
}
2 changes: 1 addition & 1 deletion src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl InputFile {

// read data and decrypt
self.reader.read_exact(&mut data)?;
let data = self.decrypter.decrypt(&mut data);
let data = self.decrypter.decrypt(&data);

// read hmac
self.reader.read_exact(&mut hmac)?;
Expand Down
Loading