mirror of
https://codeberg.org/scip/note.git
synced 2025-12-16 20:21:04 +01:00
ADDED: New backend added: NOTEDB::pwsafe3, which adds support to store
notes in a Password Safe v3 database. FIXED: -d didn't work, because of a typo in mode assignment.
This commit is contained in:
10
Changelog
10
Changelog
@@ -1,3 +1,13 @@
|
|||||||
|
1.3.8:
|
||||||
|
ADDED: New backend added: NOTEDB::pwsafe3, which adds support to store
|
||||||
|
notes in a Password Safe v3 database.
|
||||||
|
FIXED: -d didn't work, because of a typo in mode assignment.
|
||||||
|
================================================================================
|
||||||
|
1.3.7:
|
||||||
|
ADDED: added ticket feature, which adds a unique id to each
|
||||||
|
new note, which persists during imports/exports. the
|
||||||
|
id is a randomly generated string.
|
||||||
|
================================================================================
|
||||||
1.3.6:
|
1.3.6:
|
||||||
ADDED: Added test cases for "make test"
|
ADDED: Added test cases for "make test"
|
||||||
ADDED: Added test for optional and required perl modules in
|
ADDED: Added test for optional and required perl modules in
|
||||||
|
|||||||
@@ -9,13 +9,14 @@ my %optional = (
|
|||||||
'Config::General' => "Required by general DB backend",
|
'Config::General' => "Required by general DB backend",
|
||||||
'DB_File' => "Required by dbm DB backend",
|
'DB_File' => "Required by dbm DB backend",
|
||||||
'DBI' => "Required by mysql DB backend",
|
'DBI' => "Required by mysql DB backend",
|
||||||
'DBD::mysql' => "Required by mysql DB backend"
|
'DBD::mysql' => "Required by mysql DB backend",
|
||||||
|
'Crypt::PWSafe3' => "Required by Password Safe v3 backend"
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach my $module (sort keys %optional) {
|
foreach my $module (sort keys %optional) {
|
||||||
eval "require $module";
|
eval "require $module";
|
||||||
if ($@) {
|
if ($@) {
|
||||||
warn("Optional module $module no installed, $optional{$module}\n");
|
warn("Optional module $module not installed, $optional{$module}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ WriteMakefile(
|
|||||||
'Getopt::Long' => 0,
|
'Getopt::Long' => 0,
|
||||||
'Fcntl' => 0,
|
'Fcntl' => 0,
|
||||||
'IO::Seekable' => 0,
|
'IO::Seekable' => 0,
|
||||||
|
'YAML' => 0,
|
||||||
},
|
},
|
||||||
($ExtUtils::MakeMaker::VERSION ge '6.31'? ('LICENSE' => 'perl', ) : ()),
|
($ExtUtils::MakeMaker::VERSION ge '6.31'? ('LICENSE' => 'perl', ) : ()),
|
||||||
'clean' => { FILES => 't/*.out t/test.cfg *~ */*~' }
|
'clean' => { FILES => 't/*.out t/test.cfg *~ */*~' }
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# this is a generic module, used by note database
|
# this is a generic module, used by note database
|
||||||
# backend modules.
|
# backend modules.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2000-2004 Thomas Linden <tom@daemon.de>
|
# Copyright (c) 2000-2012 Thomas Linden <tom@daemon.de>
|
||||||
|
|
||||||
|
|
||||||
package NOTEDB;
|
package NOTEDB;
|
||||||
@@ -10,7 +10,7 @@ package NOTEDB;
|
|||||||
use Exporter ();
|
use Exporter ();
|
||||||
use vars qw(@ISA @EXPORT $crypt_supported);
|
use vars qw(@ISA @EXPORT $crypt_supported);
|
||||||
|
|
||||||
$NOTEDB::VERSION = "1.31";
|
$NOTEDB::VERSION = "1.32";
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
# make sure, it works, otherwise encryption
|
# make sure, it works, otherwise encryption
|
||||||
|
|||||||
589
NOTEDB/pwsafe3.pm
Normal file
589
NOTEDB/pwsafe3.pm
Normal file
@@ -0,0 +1,589 @@
|
|||||||
|
# Perl module for note
|
||||||
|
# pwsafe3 backend. see docu: perldoc NOTEDB::pwsafe3
|
||||||
|
|
||||||
|
package NOTEDB::pwsafe3;
|
||||||
|
|
||||||
|
$NOTEDB::pwsafe3::VERSION = "1.00";
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use Data::Dumper;
|
||||||
|
use Time::Local;
|
||||||
|
use Crypt::PWSafe3;
|
||||||
|
|
||||||
|
use NOTEDB;
|
||||||
|
|
||||||
|
use Fcntl qw(LOCK_EX LOCK_UN);
|
||||||
|
|
||||||
|
use Exporter ();
|
||||||
|
use vars qw(@ISA @EXPORT);
|
||||||
|
@ISA = qw(NOTEDB Exporter);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub new {
|
||||||
|
my($this, %param) = @_;
|
||||||
|
|
||||||
|
my $class = ref($this) || $this;
|
||||||
|
my $self = {};
|
||||||
|
bless($self,$class);
|
||||||
|
|
||||||
|
$self->{dbname} = $param{dbname} || File::Spec->catfile($ENV{HOME}, ".notedb");
|
||||||
|
|
||||||
|
$self->{mtime} = $self->get_stat();
|
||||||
|
$self->{unread} = 1;
|
||||||
|
$self->{data} = {};
|
||||||
|
$self->{LOCKFILE} = $param{dbname} . "~LOCK";
|
||||||
|
|
||||||
|
return $self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub DESTROY {
|
||||||
|
# clean the desk!
|
||||||
|
}
|
||||||
|
|
||||||
|
sub version {
|
||||||
|
my $this = shift;
|
||||||
|
return $NOTEDB::pwsafe3::VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_stat {
|
||||||
|
my ($this) = @_;
|
||||||
|
my $mtime = (stat($this->{dbname}))[9];
|
||||||
|
return $mtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub filechanged {
|
||||||
|
my ($this) = @_;
|
||||||
|
my $current = $this->get_stat();
|
||||||
|
if ($current > $this->{mtime}) {
|
||||||
|
$this->{mtime} = $current;
|
||||||
|
return $current;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_del_all {
|
||||||
|
my $this = shift;
|
||||||
|
unlink $this->{dbname};
|
||||||
|
open(TT,">$this->{dbname}") or die "Could not create $this->{dbname}: $!\n";
|
||||||
|
close (TT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub get_single {
|
||||||
|
my($this, $num) = @_;
|
||||||
|
my($address, $note, $date, $buffer, $n, $t, $buffer, );
|
||||||
|
|
||||||
|
my %data = $this->get_all();
|
||||||
|
|
||||||
|
return ($data{$num}->{note}, $data{$num}->{date});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub get_all {
|
||||||
|
my $this = shift;
|
||||||
|
my($num, $note, $date, %res);
|
||||||
|
|
||||||
|
if ($this->unchanged) {
|
||||||
|
return %{$this->{cache}};
|
||||||
|
}
|
||||||
|
|
||||||
|
my %data = $this->_retrieve();
|
||||||
|
|
||||||
|
foreach my $num (keys %data) {
|
||||||
|
($res{$num}->{date}, $res{$num}->{note}) = $this->_pwsafe3tonote($data{$num}->{note});
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->cache(%res);
|
||||||
|
return %res;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub import_data {
|
||||||
|
my ($this, $data) = @_;
|
||||||
|
|
||||||
|
my $fh;
|
||||||
|
|
||||||
|
if (-s $this->{dbname}) {
|
||||||
|
$fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
|
||||||
|
flock $fh, LOCK_EX;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $key = $this->_getpass();
|
||||||
|
|
||||||
|
eval {
|
||||||
|
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
|
||||||
|
|
||||||
|
foreach my $num (keys %{$data}) {
|
||||||
|
my $checksum = $this->get_nextnum();
|
||||||
|
my %record = $this->_notetopwsafe3($checksum, $data->{$num}->{note}, $data->{$num}->{date});
|
||||||
|
|
||||||
|
my $rec = new Crypt::PWSafe3::Record();
|
||||||
|
$rec->uuid($record{uuid});
|
||||||
|
$vault->addrecord($rec);
|
||||||
|
$vault->modifyrecord($record{uuid}, %record);
|
||||||
|
}
|
||||||
|
|
||||||
|
$vault->save();
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
print "Exception caught:\n$@\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval {
|
||||||
|
flock $fh, LOCK_UN;
|
||||||
|
$fh->close();
|
||||||
|
};
|
||||||
|
|
||||||
|
$this->{keepkey} = 0;
|
||||||
|
$this->{key} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_nextnum {
|
||||||
|
my $this = shift;
|
||||||
|
my($num, $te, $me, $buffer);
|
||||||
|
|
||||||
|
my $ug = new Data::UUID;
|
||||||
|
|
||||||
|
$this->{nextuuid} = unpack('H*', $ug->create());
|
||||||
|
$num = $this->_uuid( $this->{nextuuid} );
|
||||||
|
|
||||||
|
return $num;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_search {
|
||||||
|
my($this, $searchstring) = @_;
|
||||||
|
my($buffer, $num, $note, $date, %res, $t, $n, $match);
|
||||||
|
|
||||||
|
my $regex = $this->generate_search($searchstring);
|
||||||
|
eval $regex;
|
||||||
|
if ($@) {
|
||||||
|
print "invalid expression: \"$searchstring\"!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$match = 0;
|
||||||
|
|
||||||
|
if ($this->unchanged) {
|
||||||
|
foreach my $num (keys %{$this->{cache}}) {
|
||||||
|
$_ = $this->{cache}{$num}->{note};
|
||||||
|
eval $regex;
|
||||||
|
if ($match) {
|
||||||
|
$res{$num}->{note} = $this->{cache}{$num}->{note};
|
||||||
|
$res{$num}->{date} = $this->{cache}{$num}->{date}
|
||||||
|
}
|
||||||
|
$match = 0;
|
||||||
|
}
|
||||||
|
return %res;
|
||||||
|
}
|
||||||
|
|
||||||
|
my %data = $this->get_all();
|
||||||
|
|
||||||
|
foreach my $num(sort keys %data) {
|
||||||
|
$_ = $data{$num}->{note};
|
||||||
|
eval $regex;
|
||||||
|
if($match)
|
||||||
|
{
|
||||||
|
$res{$num}->{note} = $data{$num}->{note};
|
||||||
|
$res{$num}->{date} = $data{$num}->{data};
|
||||||
|
}
|
||||||
|
$match = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return %res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub set_edit {
|
||||||
|
my($this, $num, $note, $date) = @_;
|
||||||
|
|
||||||
|
my %data = $this->_retrieve();
|
||||||
|
|
||||||
|
my %record = $this->_notetopwsafe3($num, $note, $date);
|
||||||
|
|
||||||
|
if (exists $data{$num}) {
|
||||||
|
$data{$num}->{note} = \%record;
|
||||||
|
$this->_store(\%record);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
%record = $this->_store(\%record, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub set_new {
|
||||||
|
my($this, $num, $note, $date) = @_;
|
||||||
|
$this->set_edit($num, $note, $date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub set_del {
|
||||||
|
my($this, $num) = @_;
|
||||||
|
|
||||||
|
my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
|
||||||
|
flock $fh, LOCK_EX;
|
||||||
|
|
||||||
|
my $key = $this->_getpass();
|
||||||
|
eval {
|
||||||
|
my $vault = new Vault($key, $this->{dbname});
|
||||||
|
$vault->delrecord($this->_getuuid($num));
|
||||||
|
|
||||||
|
$vault->write_to_file($this->{dbname}, $key);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
print "Exception caught:\n$@\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
flock $fh, LOCK_UN;
|
||||||
|
$fh->close();
|
||||||
|
|
||||||
|
# finally re-read the db, so that we always have the latest data
|
||||||
|
$this->_retrieve($key);
|
||||||
|
$this->changed;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_recountnums {
|
||||||
|
my($this) = @_;
|
||||||
|
# unsupported
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub _store {
|
||||||
|
my ($this, $record, $create) = @_;
|
||||||
|
|
||||||
|
my $fh;
|
||||||
|
|
||||||
|
if (-s $this->{dbname}) {
|
||||||
|
$fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
|
||||||
|
flock $fh, LOCK_EX;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $key = $this->_getpass();
|
||||||
|
eval {
|
||||||
|
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
|
||||||
|
if ($create) {
|
||||||
|
my $rec = new Crypt::PWSafe3::Record();
|
||||||
|
$rec->uuid($record->{uuid});
|
||||||
|
$vault->addrecord($rec);
|
||||||
|
$vault->modifyrecord($record->{uuid}, %{$record});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$vault->modifyrecord($record->{uuid}, %{$record});
|
||||||
|
}
|
||||||
|
$vault->save();
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
print "Exception caught:\n$@\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eval {
|
||||||
|
flock $fh, LOCK_UN;
|
||||||
|
$fh->close();
|
||||||
|
};
|
||||||
|
|
||||||
|
# finally re-read the db, so that we always have the latest data
|
||||||
|
$this->_retrieve($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _retrieve {
|
||||||
|
my ($this, $key) = @_;
|
||||||
|
my $file = $this->{dbname};
|
||||||
|
if (-s $file) {
|
||||||
|
if ($this->filechanged() || $this->{unread}) {
|
||||||
|
my $fh = new FileHandle "<$this->{dbname}" or die "could not open $this->{dbname}\n";
|
||||||
|
flock $fh, LOCK_EX;
|
||||||
|
|
||||||
|
my %data;
|
||||||
|
if (! $key) {
|
||||||
|
$key = $this->_getpass();
|
||||||
|
}
|
||||||
|
eval {
|
||||||
|
my $vault = new Crypt::PWSafe3(password => $key, file => $this->{dbname});
|
||||||
|
|
||||||
|
my @records = $vault->getrecords();
|
||||||
|
|
||||||
|
foreach my $record (@records) {
|
||||||
|
my $num = $this->_uuid( $record->uuid );
|
||||||
|
my %entry = (
|
||||||
|
uuid => $record->uuid,
|
||||||
|
title => $record->title,
|
||||||
|
user => $record->user,
|
||||||
|
passwd => $record->passwd,
|
||||||
|
notes => $record->notes,
|
||||||
|
group => $record->group,
|
||||||
|
lastmod=> $record->lastmod,
|
||||||
|
);
|
||||||
|
$data{$num}->{note} = \%entry;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
print "Exception caught:\n$@\n";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
flock $fh, LOCK_UN;
|
||||||
|
$fh->close();
|
||||||
|
|
||||||
|
$this->{unread} = 0;
|
||||||
|
$this->{data} = \%data;
|
||||||
|
return %data;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return %{$this->{data}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _pwsafe3tonote {
|
||||||
|
#
|
||||||
|
# convert pwsafe3 record to note record
|
||||||
|
my ($this, $record) = @_;
|
||||||
|
my $date = scalar localtime($record->{lastmod});
|
||||||
|
chomp $date;
|
||||||
|
my $note;
|
||||||
|
if ($record->{group}) {
|
||||||
|
my $group = $record->{group};
|
||||||
|
# convert group separator
|
||||||
|
$group =~ s#\.#/#g;
|
||||||
|
$note = "/$group/\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# pwsafe3 uses windows newlines, so convert ours
|
||||||
|
$record->{notes} =~ s/\r\n/\n/gs;
|
||||||
|
|
||||||
|
#
|
||||||
|
# we do NOT add user and password fields here extra
|
||||||
|
# because if it is contained in the note, from were
|
||||||
|
# it was extracted initially, where it remains anyway
|
||||||
|
$note .= "$record->{title}\n$record->{notes}";
|
||||||
|
|
||||||
|
return ($date, $note);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _notetopwsafe3 {
|
||||||
|
#
|
||||||
|
# convert note record to pwsafe3 record
|
||||||
|
# only used on create or save
|
||||||
|
#
|
||||||
|
# this one is the critical part, because the two
|
||||||
|
# record types are fundamentally incompatible.
|
||||||
|
# we parse our record and try to guess the values
|
||||||
|
# required for pwsafe3
|
||||||
|
#
|
||||||
|
# expected input for note:
|
||||||
|
# /path/ -> group, optional
|
||||||
|
# any text -> title
|
||||||
|
# User: xxx -> user
|
||||||
|
# Password: xxx -> passwd
|
||||||
|
# anything else -> notes
|
||||||
|
#
|
||||||
|
# expected input for date:
|
||||||
|
# 23.02.2010 07:56:27
|
||||||
|
my ($this, $num, $text, $date) = @_;
|
||||||
|
my ($group, $title, $user, $passwd, $notes, $ts, $content);
|
||||||
|
if ($text =~ /^\//) {
|
||||||
|
($group, $title, $content) = split /\n/, $text, 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
($title, $content) = split /\n/, $text, 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $passwd = '';
|
||||||
|
if ($content =~ /(user|username|login|account|benutzer):\s*(.+)/i) {
|
||||||
|
$user = $2;
|
||||||
|
}
|
||||||
|
if ($content =~ /(password|pass|passwd|kennwort|pw):\s*(.+)/i) {
|
||||||
|
$passwd = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1 2 3 5 6 7
|
||||||
|
if ($date =~ /^(\d\d)\.(\d\d)\.(\{4}) (\d\d):(\d\d):(\d\d)$/) {
|
||||||
|
$ts = timelocal($7, $6, $5, $1, $2-1, $3-1900);
|
||||||
|
}
|
||||||
|
|
||||||
|
# make our topics pwsafe3 compatible groups
|
||||||
|
$group =~ s#^/##;
|
||||||
|
$group =~ s#/$##;
|
||||||
|
$group =~ s#/#.#g;
|
||||||
|
|
||||||
|
# pwsafe3 uses windows newlines, so convert ours
|
||||||
|
$content =~ s/\n/\r\n/gs;
|
||||||
|
|
||||||
|
my %record = (
|
||||||
|
uuid => $this->_getuuid($num),
|
||||||
|
user => $user,
|
||||||
|
passwd => $passwd,
|
||||||
|
group => $group,
|
||||||
|
title => $title,
|
||||||
|
lastmod=> $ts,
|
||||||
|
notes => $content,
|
||||||
|
);
|
||||||
|
|
||||||
|
return %record;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _uuid {
|
||||||
|
#
|
||||||
|
# Convert a given pwsafe3 uuid to a number
|
||||||
|
# and store them for recursive access
|
||||||
|
my ($this, $uuid) = @_;
|
||||||
|
if (exists $this->{uuidnum}->{$uuid}) {
|
||||||
|
return $this->{uuidnum}->{$uuid};
|
||||||
|
}
|
||||||
|
|
||||||
|
my $intuuid = $uuid;
|
||||||
|
$intuuid =~ s/[\-]//g;
|
||||||
|
$intuuid = unpack('h32', $intuuid);
|
||||||
|
my $cuid = $intuuid;
|
||||||
|
my $checksum;
|
||||||
|
while () {
|
||||||
|
$checksum = unpack("%16C*", $cuid) - 1600;
|
||||||
|
while ($checksum < 0) {
|
||||||
|
$checksum++; # avoid negative numbers
|
||||||
|
}
|
||||||
|
if (! exists $this->{numuuid}->{$checksum}) {
|
||||||
|
$this->{uuidnum}->{$uuid} = $checksum;
|
||||||
|
$this->{numuuid}->{$checksum} = $uuid;
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$cuid .= $.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $checksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _getuuid {
|
||||||
|
my ($this, $num) = @_;
|
||||||
|
return $this->{numuuid}->{$num};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _getpass {
|
||||||
|
#
|
||||||
|
# We're doing this here ourselfes
|
||||||
|
# because the note way of handling encryption
|
||||||
|
# doesn't work with pwsafe3, we can't hold a cipher
|
||||||
|
# structure in memory, because pwsafe3 handles this
|
||||||
|
# itself.
|
||||||
|
# Instead we ask for the password everytime we want
|
||||||
|
# to fetch data from the actual file OR want to write
|
||||||
|
# to it. To minimize reads, we use caching by default.
|
||||||
|
my($this) = @_;
|
||||||
|
if ($this->{key}) {
|
||||||
|
return $this->{key};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $key;
|
||||||
|
print "password: ";
|
||||||
|
eval {
|
||||||
|
local($|) = 1;
|
||||||
|
local(*TTY);
|
||||||
|
open(TTY,"/dev/tty") or die "No /dev/tty!";
|
||||||
|
system ("stty -echo </dev/tty") and die "stty failed!";
|
||||||
|
chomp($key = <TTY>);
|
||||||
|
print STDERR "\r\n";
|
||||||
|
system ("stty echo </dev/tty") and die "stty failed!";
|
||||||
|
close(TTY);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
$key = <>;
|
||||||
|
}
|
||||||
|
if ($this->{keepkey}) {
|
||||||
|
$this->{key} = $key;
|
||||||
|
}
|
||||||
|
return $key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1; # keep this!
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
NOTEDB::pwsafe3 - module lib for accessing a notedb from perl
|
||||||
|
|
||||||
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
|
# include the module
|
||||||
|
use NOTEDB;
|
||||||
|
|
||||||
|
# create a new NOTEDB object
|
||||||
|
$db = new NOTEDB("text", "/home/tom/.notedb", 4096, 24);
|
||||||
|
|
||||||
|
# decide to use encryption
|
||||||
|
# $key is the cipher to use for encryption
|
||||||
|
# $method must be either Crypt::IDEA or Crypt::DES
|
||||||
|
# you need Crypt::CBC, Crypt::IDEA and Crypt::DES to have installed.
|
||||||
|
$db->use_crypt($key,$method);
|
||||||
|
|
||||||
|
# do not use encryption
|
||||||
|
# this is the default
|
||||||
|
$db->no_crypt;
|
||||||
|
|
||||||
|
# get a single note
|
||||||
|
($note, $date) = $db->get_single(1);
|
||||||
|
|
||||||
|
# search for a certain note
|
||||||
|
%matching_notes = $db->get_search("somewhat");
|
||||||
|
# format of returned hash:
|
||||||
|
#$matching_notes{$numberofnote}->{'note' => 'something', 'date' => '23.12.2000 10:33:02'}
|
||||||
|
|
||||||
|
# get all existing notes
|
||||||
|
%all_notes = $db->get_all();
|
||||||
|
# format of returnes hash like the one from get_search above
|
||||||
|
|
||||||
|
# get the next noteid available
|
||||||
|
$next_num = $db->get_nextnum();
|
||||||
|
|
||||||
|
# modify a certain note
|
||||||
|
$db->set_edit(1, "any text", "23.12.2000 10:33:02");
|
||||||
|
|
||||||
|
# create a new note
|
||||||
|
$db->set_new(5, "any new text", "23.12.2000 10:33:02");
|
||||||
|
|
||||||
|
# delete a certain note
|
||||||
|
$db->set_del(5);
|
||||||
|
|
||||||
|
# turn on encryption. CryptMethod must be IDEA, DES or BLOWFISH
|
||||||
|
$db->use_crypt("passphrase", "CryptMethod");
|
||||||
|
|
||||||
|
# turn off encryption. This is the default.
|
||||||
|
$db->no_crypt();
|
||||||
|
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
You can use this module for accessing a note database. This backend uses
|
||||||
|
a text file for storage and Config::General for accessing the file.
|
||||||
|
|
||||||
|
Currently, NOTEDB module is only used by note itself. But feel free to use it
|
||||||
|
within your own project! Perhaps someone want to implement a webinterface to
|
||||||
|
note...
|
||||||
|
|
||||||
|
=head1 USAGE
|
||||||
|
|
||||||
|
please see the section SYNOPSIS, it says it all.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Thomas Linden <tom AT linden DOT at>
|
||||||
|
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
|
||||||
4
README
4
README
@@ -1,4 +1,4 @@
|
|||||||
note 1.3.5 by Thomas Linden, 07/19/2009
|
note 1.3.8 by Thomas Linden, 02/01/2012
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
@@ -214,4 +214,4 @@ and I'll add you.
|
|||||||
Last changed
|
Last changed
|
||||||
============
|
============
|
||||||
|
|
||||||
07/19/2009
|
02/01/2012
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# note 1.3.5 -*- sh -*-
|
# note 1.3.8 -*- sh -*-
|
||||||
#
|
#
|
||||||
# This is a sample config for the note script
|
# This is a sample config for the note script
|
||||||
# There are useful defaults set in note itself.
|
# There are useful defaults set in note itself.
|
||||||
#
|
#
|
||||||
# Copy it to your $HOME as .noterc
|
# Copy it to your $HOME as .noterc
|
||||||
#
|
#
|
||||||
# note is Copyright (c) 1999-2009 Thomas Linden.
|
# note is Copyright (c) 1999-2012 Thomas Linden.
|
||||||
# You can contact me per email: <tom at linden dot at>
|
# You can contact me per email: <tom at linden dot at>
|
||||||
#
|
#
|
||||||
# Comments start with #, empty lines will be ignored.
|
# Comments start with #, empty lines will be ignored.
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
# to use. Please refer to the corresponding documentation
|
# to use. Please refer to the corresponding documentation
|
||||||
# for closer information about the certain backend!
|
# for closer information about the certain backend!
|
||||||
# Currently supported types: "binary", "dbm", "mysql",
|
# Currently supported types: "binary", "dbm", "mysql",
|
||||||
# "general" or "text".
|
# "general", "dumper", "pwsafe3" or "text".
|
||||||
# You must also edit/uncomment one section below for the
|
# You must also edit/uncomment one section below for the
|
||||||
# backend you want to use!
|
# backend you want to use!
|
||||||
dbdriver = binary
|
dbdriver = binary
|
||||||
@@ -66,11 +66,41 @@ dbm::directory = ~/.notedbm # directory
|
|||||||
general::dbname = ~/.notedb # filename
|
general::dbname = ~/.notedb # filename
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# TEXT backend
|
# TEXT backend
|
||||||
text::dbname = ~/.notedb # filename
|
text::dbname = ~/.notedb # filename
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# DUMPER backend
|
||||||
|
dumper::dbname = ~/.notedb # filename
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Password Safe v3 backend
|
||||||
|
# Some notes on this one:
|
||||||
|
# This backend maintains encryption itself, which is
|
||||||
|
# mandatory as well. So you'll have to disable encryption
|
||||||
|
# (UseEncryption = NO)!
|
||||||
|
#
|
||||||
|
# The Password Safe v3 file has its own fields for
|
||||||
|
# password and username, which note doesn't have. To be
|
||||||
|
# compatible, the pwsafe3 backend parses the note text
|
||||||
|
# for those fields and stores them accordignly to the db:
|
||||||
|
#
|
||||||
|
# For username field: user|username|login|account|benutzer
|
||||||
|
# For passwd field: password|pass|passwd|kennwort|pw
|
||||||
|
#
|
||||||
|
# If it doesn't find it, it will put empty strings
|
||||||
|
# into the pwsafe3 database.
|
||||||
|
#
|
||||||
|
# The pwsafe3 database can be accessed by Password Safe
|
||||||
|
# (see: http://passwordsafe.sourceforge.net/) or other
|
||||||
|
# tools which support the format (see:
|
||||||
|
# http://passwordsafe.sourceforge.net/relatedprojects.shtml)
|
||||||
|
pwsafe3::dbname = ~/db.psafe3 # filename
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# You can use encryption with note, that means notes and
|
# You can use encryption with note, that means notes and
|
||||||
|
|||||||
7
note.pod
7
note.pod
@@ -431,7 +431,12 @@ input and overwrites an existing database.
|
|||||||
|
|
||||||
Before you use the B<-o> switch, I consider you to make a backup!
|
Before you use the B<-o> switch, I consider you to make a backup!
|
||||||
|
|
||||||
|
=head3 BACKUP FILE FORMAT
|
||||||
|
|
||||||
|
B<Caution>: since version 1.3.8 note uses a new file format
|
||||||
|
for backups: YAML. The old format is only supported by the
|
||||||
|
B<-I> option to import old backups. New backups are always
|
||||||
|
created as YAML files. See L<YAML>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -530,6 +535,6 @@ Thomas Linden <tom at linden dot at>
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
1.3.6 (07/20/2009)
|
1.3.8 (02/01/2012)
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|||||||
Reference in New Issue
Block a user