File-KDBX

 view release on metacpan or  search on metacpan

lib/File/KDBX/Loader/XML.pm  view on Meta::CPAN

        # try again after reading in all the attributes
        $reader->moveToFirstAttribute;
        while ($self->_reader->readAttributeValue == 1) {}
        $reader->moveToElement;

        $value = trim($reader->getAttribute($name));
    }

    return $default if !defined $value;

    my $decoded = eval { _decode_primitive($value, $type) };
    if (my $err = $@) {
        ref $err and $err->details(attribute => $name, node => $reader->nodePath, line => $reader->lineNumber);
        throw $err
    }

    return $decoded;
}

sub _read_xml_content {
    my $self = shift;
    my $type = shift;
    my $reader = $self->_reader;

    $reader->read if !$reader->isEmptyElement;  # step into element
    return '' if !$reader->hasValue;

    my $content = trim($reader->value);

    my $decoded = eval { _decode_primitive($content, $type) };
    if (my $err = $@) {
        ref $err and $err->details(node => $reader->nodePath, line => $reader->lineNumber);
        throw $err;
    }

    return $decoded;
}

##############################################################################

sub _decode_primitive { goto &{__PACKAGE__."::_decode_$_[1]"} }

sub _decode_binary {
    local $_ = shift;
    return '' if !defined || (ref && !defined $$_);
    $_ = eval { decode_b64(ref $_ ? $$_ : $_) };

lib/File/KDBX/Safe.pm  view on Meta::CPAN

    $cipher->finish;
    $self->{counter} = 0;

    for my $item (@{$self->{items}}) {
        my $string  = $item->{str};
        my $cleanup = erase_scoped \$item->{val};
        my $str_ref;
        if (is_scalarref($string)) {
            $$string = $cipher->crypt(\$item->{val});
            if (my $encoding = $item->{enc}) {
                my $decoded = decode($encoding, $string->{value});
                erase $string;
                $$string = $decoded;
            }
            $str_ref = $string;
        }
        elsif (is_hashref($string)) {
            $string->{value} = $cipher->crypt(\$item->{val});
            if (my $encoding = $item->{enc}) {
                my $decoded = decode($encoding, $string->{value});
                erase \$string->{value};
                $string->{value} = $decoded;
            }
            $str_ref = \$string->{value};
        }
        else {
            die 'Unexpected';
        }
        if (my $filter = $item->{filter}) {
            my $filtered = $filter->($$str_ref);
            erase $str_ref;
            $$str_ref = $filtered;

lib/File/KDBX/Safe.pm  view on Meta::CPAN

sub peek {
    my $self = shift;
    my $string = shift;

    my $item = $self->{index}{refaddr($string)} // return;

    my $cipher = $self->cipher->dup(offset => $item->{off});

    my $value = $cipher->crypt(\$item->{val});
    if (my $encoding = $item->{enc}) {
        my $decoded = decode($encoding, $value);
        erase $value;
        return $decoded;
    }
    return $value;
}


sub cipher {
    my $self = shift;
    $self->{cipher} //= do {
        require File::KDBX::Cipher;
        File::KDBX::Cipher->new(stream_id => STREAM_ID_CHACHA20, key => random_bytes(64));

t/memory-protection.t  view on Meta::CPAN


    pipe(my $read, my $write) or die "pipe failed: $!\n";

    defined(my $pid = fork) or die "fork failed: $!\n";
    if (!$pid) { # child
        close($read);

        my $exit_status = run_doomed_child($code, $seed);
        my $dumped = $exit_status & 127 && $exit_status & 128;

        my @decoded_strings = map { decode_b64($_) } @strings;

        my @matches = file_grep('core', @decoded_strings);
        print $write join('|', $dumped, -f 'core' ? 1 : 0, @matches);
        close($write);

        POSIX::_exit(0);
    }

    close($write);
    my $results = do { local $/; <$read> };

    waitpid($pid, 0);



( run in 0.281 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )