Firefox-Sync-Client
view release on metacpan or search on metacpan
lib/Firefox/Sync/Client.pm view on Meta::CPAN
=item get_passwords()
Returns all synchronized passwords. The passwords are returned
unencrypted.
=cut
sub get_passwords {
my $self = shift;
return get_raw_collection($self, 'passwords');
}
=item get_prefs()
Returns the synchronized browser preferences.
=cut
sub get_prefs {
my $self = shift;
return get_raw_collection($self, 'prefs');
}
=item get_tabs()
Returns an array of tabs opened on each Sync client / Browser.
=cut
sub get_tabs {
my $self = shift;
return get_raw_collection($self, 'tabs');
}
sub resolve_children {
my ($collection, $bm) = @_;
if ($bm->{'payload'}->{'children'} and scalar($bm->{'payload'}->{'children'})) {
my @children;
foreach my $child_id (@{$bm->{'payload'}->{'children'}}) {
my $child_bm;
foreach (@$collection) {
next unless $_->{'id'} eq $child_id;
$child_bm = $_;
push @children, $_;
}
resolve_children($collection, $child_bm);
}
$bm->{'payload'}->{'children'} = \@children;
}
}
sub sync_key_to_enc_key {
my $self = shift;
my $s_key = $self->{'sync_key'};
$s_key =~ s/8/l/g;
$s_key =~ s/9/o/g;
$s_key =~ s/-//g;
$s_key = uc($s_key);
my $raw_bits = MIME::Base32::decode($s_key);
my $key = hmac_sha256('Sync-AES_256_CBC-HMAC256' . $self->{'username'} . "\x01", $raw_bits);
return $key;
}
sub fetch_bulk_keys {
my $self = shift;
my $json = fetch_json($self, $self->{'base_url'} . 'storage/crypto/keys');
my $keys = decrypt_collection($self, decode_json($json->{'payload'}), 'crypto');
my $default_keys = decode_json($keys);
$self->{'bulk_keys'}{'default'} = decode_base64($default_keys->{'default'}[0]);
return $self->{'bulk_keys'};
}
sub decrypt_payload {
my ($self, $payload, $key) = @_;
my $c = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_CBC());
$c->set_iv(decode_base64($payload->{'IV'}));
my $data = $c->decrypt(decode_base64($payload->{'ciphertext'}));
$data = repair_json($self, $data);
return $data;
}
sub decrypt_collection {
my ($self, $payload, $collection) = @_;
my $key;
if ($collection eq 'crypto') {
$key = sync_key_to_enc_key($self);
}
else {
if ($self->{'bulk_keys'}{$collection}) {
$key = $self->{'bulk_keys'}{$collection};
}
else {
$key = $self->{'bulk_keys'}{'default'};
}
}
return decrypt_payload($self, $payload, $key);
}
sub fetch_json {
my ($self, $url) = @_;
my $res;
if (defined $self->{'cachefile'}) {
$self->{'cache'} = retrieve($self->{'cachefile'}) unless (-z $self->{'cachefile'});
if (defined $self->{'cache'}->{$url} and (time - $self->{'cache'}->{$url . '_ts'} <= $self->{'cachelifetime'})) {
# We have a cache hit, so simply return it
return decode_json($self->{'cache'}->{$url}->content);
}
else {
# Really do the request
$res = really_fetch_json($self, $url);
# Cache the request
$self->{'cache'}->{$url} = $res;
$self->{'cache'}->{$url . '_ts'} = time;
store($self->{'cache'}, $self->{'cachefile'});
}
}
else {
# We don't have a cache file, so simply request the data and return it
$res = really_fetch_json($self, $url);
}
return decode_json($res->content);
}
sub really_fetch_json {
my ($self, $url) = @_;
# Initialize LWP
( run in 1.684 second using v1.01-cache-2.11-cpan-e1769b4cff6 )