#!/usr/bin/perl -w

# Manage GNU Keyring database entries
#
# Dobrica Pavlinusic <dpavlin@rot13.org> 2000-08-01
# 
# now with ability to add records 2000-09-08
#
# http://www.rot13.org/~dpavlin/
# http://gnukeyring.sourceforge.net/
#
# PDA::Pilot comes with source of pilot-link, others are from CPAN

use strict;
use PDA::Pilot;
use Crypt::DES; 
use MD5;
use Getopt::Std;
use Data::Dumper;

my %opts;
$opts{d} = "Keys-Gtkr.pdb";

if (! getopts('p:d:a',\%opts) or !exists $opts{p}) {
	print "Usage: $0 -p password [-d dbname] [-a]\n";
	print "Dump or add (-a) all records from your GNU keyring database protected\n";
	print "by password.\n\n";
	exit;
}

die "Can't open $opts{d}" if (! -f $opts{d} || ! -r $opts{d});
my $db = PDA::Pilot::File::open($opts{d});

my $key = MD5->hash("$opts{p}");
my $c1 = new DES substr($key,0,8);
my $c2 = new DES substr($key,8,8);

if (! $opts{a}) {

	my $i=0;
	while(defined(my $r = $db->getRecord($i++))) {
		my ($name,$raw)=split(/\000/,$r->{raw},2);
		print "Name: $name\n";
		die "record not 8 byte padded" if (length($raw) % 8) != 0;
		my $out="";
		for (my $j=0; $j<int(length($raw) / 8); $j++) {
			my $to=$c1->decrypt( substr($raw,$j*8,8) );
			my $other=$c2->encrypt($to);
			$to=$c1->decrypt($other);
			$out.=$to;
		}
		my ($acc,$pass,$note,$rest)=split(/\000/,$out,4);
		my $date=(unpack("n",$rest));
		my $yyyy = int($date/512);
		my $mm = int(($date-$yyyy*512)/32);
		my $dd = $date-$yyyy*512-$mm*32;
		$yyyy+=1904;
		printf("len: %d date: %08x %d ",length($rest),$date,$date);
#		print scalar(localtime($date+$deltaT));
#		print "--\n$out\n--";
		print "Account: $acc\nPassword: $pass\nNote:\n$note\n";
		printf("Date: %04d-%02d-%02d\n\n",$yyyy,$mm,$dd);
	}

} else {

	print "Name: ";
	my $name=<STDIN>;
	print "Account: ";
	my $acc=<STDIN>;
	print "Password: ";
	my $pass=<STDIN>;

	my $i=0; my $id; my $r;
	while(defined($r = $db->getRecord($i++))) {
		if ($id < $r->{id}) { $id=$r->{id}; }
		print Dumper($r);
	}
	while($db->checkID($id)) { $id++; }

	my $raw=join("\000",$name,$acc,$pass,"xxxx");
	$raw.="\000" x (8-(length($raw) % 8));

	die "record not 8 byte padded" if (length($raw) % 8) != 0;
	my $out="";

	for (my $j=0; $j<int(length($raw) / 8); $j++) {
		my $to=$c1->decrypt( substr($raw,$j*8,8) );
		my $other=$c2->encrypt($to);
		$to=$c1->decrypt($other);
		$out.=$to;
	}



	$r = PDA::Pilot::Database->record;
	$r->{'secret'} => 0;
	$r->{'deleted'} => 0;
	$r->{'raw'} => $name.'\000'.$out;
	$r->{'id'} => 0;
	$r->{'category'} => '0';

	PDA::Pilot::File::append_record($db, $name, 0, $id);

	$db->addRecord($r);

}

