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 )