view release on metacpan or search on metacpan
t/09-configuration.t CTK::Configuration
t/10-log.t CTK::Log
t/11-plugins.t Plugins testing
t/12-app.t CTK::App
t/13-void.t Void tests
t/14-plugin-file.t Plugin: File
t/15-flags.t CTK::Util: Flags test
t/16-plugin-archive.t Plugin: Archive
t/17-crypt-tcd04.t Crypt: TCD04
t/18-crypt.t Crypt
t/19-crypt-gpg.t Crypt: GPG
t/20-plugin-net.t Plugin: Net
t/21-sendmail.t Sendmail testing
t/22-dbi.t CTK::DBI
t/23-attrs.t CTK::Util::read_attributes in the new edition
t/24-digest.t Digest tests
t/25-plugins-ext.t Extended plugins test (since 2.04)
t/26-filepid.t CTK::FilePid
t/27-timeout.t Timeout check
t/28-cgu-lvalue.t LastValue for value method
lib/CTK/Crypt.pm view on Meta::CPAN
=head1 NAME
CTK::Crypt - Cryptography frontend module
=head1 VERSION
Version 1.73
=head1 SYNOPSIS
use CTK::Util qw/gpg_init gpg_encrypt gpg_decrypt/;
my $gpg_instance = gpg_init(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
gpg_encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $CTK::Crypt::ERROR );
gpg_decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $CTK::Crypt::ERROR );
tcd_encrypt( "file.txt", "file.tcd" )
or die( $CTK::Crypt::ERROR );
tcd_decrypt( "file.tcd", "file.txt" )
or die( $CTK::Crypt::ERROR );
=head1 DESCRIPTION
Cryptography frontend module
=over 8
=item B<gpg_init>
my $gpg_instance = gpg_init(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
Initialize GPG instance
See L<CTK::Crypt::GPG>
=item B<gpg_decrypt>
$gpg_instance->decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $CTK::Crypt::ERROR );
GPG (PGP) Decrypting the files
See L<CTK::Crypt::GPG>
=item B<gpg_encrypt>
$gpg_instance->encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $CTK::Crypt::ERROR );
GPG (PGP) Encrypting the files
See L<CTK::Crypt::GPG>
=item B<tcd_decrypt>
lib/CTK/Crypt.pm view on Meta::CPAN
=item B<:all>
Will be exported all functions
=item B<:tcd04>
Will be exported following functions:
tcd_encrypt, tcd_decrypt
=item B<:gpg>
Will be exported following functions:
gpg_init, gpg_encrypt, gpg_decrypt
=back
=head1 HISTORY
See C<Changes> file
=head1 DEPENDENCIES
L<CTK::Crypt::GPG>, L<CTK::Crypt::TCD04>
lib/CTK/Crypt.pm view on Meta::CPAN
use base qw/Exporter/;
use IO::File;
use CTK::Crypt::GPG;
use CTK::Crypt::TCD04;
use constant BUFFER_SIZE => 32 * 1024; # 32kB
@EXPORT_OK = (qw/
gpg_init gpg_encrypt gpg_decrypt
tcd_encrypt tcd_decrypt
/);
%EXPORT_TAGS = (
tcd04 => [qw/tcd_encrypt tcd_decrypt/],
gpg => [qw/gpg_init gpg_encrypt gpg_decrypt/],
all => [@EXPORT_OK],
);
my $GPG_INSTANCE;
sub gpg_init {
return $GPG_INSTANCE = CTK::Crypt::GPG->new(@_);
}
sub gpg_encrypt {
$ERROR = "";
my $st = $GPG_INSTANCE->encrypt(@_);
$ERROR = $GPG_INSTANCE->error unless $st;
return $st;
}
sub gpg_decrypt {
$ERROR = "";
my $st = $GPG_INSTANCE->decrypt(@_);
$ERROR = $GPG_INSTANCE->error unless $st;
return $st;
}
sub tcd_encrypt {
my $filein = shift;
my $fileout = shift;
unless (defined($filein) && length($filein) && -e $filein) {
$ERROR = sprintf("File not found \"%s\"", $filein // "");
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
CTK::Crypt - GPG Crypt backend
=head1 VERSION
Version 1.01
=head1 SYNOPSIS
use CTK::Crypt::GPG;
my $gpg = CTK::Crypt::GPG->new(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
$gpg->encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $gpg->error );
$gpg->decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $gpg->error );
=head1 DESCRIPTION
GPG Crypt backend
See L<http://www.gnupg.org> (GPG4Win - L<http://gpg4win.org>) for details
For start working with this module You need create public and private GPG keys:
gpg --full-gen-key
Example of interaction (test account):
> Anonymous
> anonymous@example.com
> Password: test
< 58E79B320D135DEE
< ADF81A296AAC9503A6135F258E79B320D135DEE
For show list of available keys run:
gpg -k
gpg -K
For export keys run:
gpg --export -a -o mypublic.key "anonymous@example.com"
gpg --export-secret-keys --batch --pinentry-mode loopback --passphrase "test" -a -o myprivate.key "anonymous@example.com"
=head2 new
my $gpg = CTK::Crypt::GPG->new(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
=over 8
=item B<gpgbin>
GPG program
For example: "/usr/bin/gpg"
Default: gpg from PATH
=item B<gpghome>, B<homedir>
GPG homedir
For example: "/gpg/homedir"
Default: /tmp/gpgXXXXX
=item B<gpgconf>
Path to GPG config file (for options storing)
For example: "/gpg/homedir/gpg.conf"
Default: /tmp/gpgXXXXX/gpg.conf
=item B<gpgopts>, B<options>
GPG default options
For example: ["verbose", "yes"]
Default: ["verbose", "yes"],
=item B<publickey>, B<pubkey>, B<pubring>
Public key path
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
=item B<recipient>, B<keyid>, B<id>, B<user>, B<keygrip>
Email, user id, keyid, or keygrip
For example: "anonymous@example.com",
=back
=head2 decrypt
$gpg->decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $gpg->error );
PGP file decrypting
=over 8
=item B<in>, B<filein>, B<filesrs>, B<infile>, B<src>
Source file (encrypted file)
=item B<out>, B<fileout>, B<filedst>, B<outfile>, B<dst>
Target file
=back
=head2 encrypt
$gpg->encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $gpg->error );
PGP file encrypting
=over 8
=item B<in>, B<filein>, B<filesrs>, B<infile>, B<src>
Source file
=item B<out>, B<fileout>, B<filedst>, B<outfile>, B<dst>
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
Enable armor-mode (as text output): yes, on, 1, enable
For example: "yes"
Default: "no"
=back
=head2 error
print $gpg->error;
Returns error string
=head1 HISTORY
See C<Changes> file
=head1 DEPENDENCIES
L<CTK::Util>, L<File::Temp>
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
=head1 TO DO
See C<TODO> file
=head1 BUGS
* none noted
=head1 SEE ALSO
L<CTK::Util>, L<http://www.gnupg.org>, L<GPG4Win|http://gpg4win.org>
=head1 AUTHOR
Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>
=head1 COPYRIGHT
Copyright (C) 1998-2022 D&D Corporation. All Rights Reserved
=head1 LICENSE
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
use vars qw/$VERSION/;
$VERSION = '1.01';
use Carp;
use CTK::Util qw(:API :FORMAT :UTIL :FILE );
use File::Temp qw();
use File::Spec;
use constant {
# GPG (GNUPG)
GPGBIN => 'gpg',
GPGCONF => 'gpg.conf',
GPGOPTS => ["verbose", "yes"],
GPGEXT => ".asc",
};
sub new {
my $class = shift;
my ($gpgbin, $gpghome, $gpgconf, $gpgopts, $pubkey, $seckey, $pass, $recipient) =
read_attributes([
['GPG','GPGBIN','BIN','CMD','COMMAND'],
['GPGHOME','GPGDIR','DIRGPG','HOMEGPG','HOMEDIR'],
['GPGCONF','CONFIG','CONF'],
['GPGOPTS','GPGOPTIONS','OPTIONS','OPTS'],
['PUBLIC','PUBLICKEY','PUP','PUBKEY','PUBRING'],
['PRIVATE','PRIV','PRIVATEKEY','SEC','SECKEY','SECRETKEY','PRIVKEY','PRIVRING','SECRING'],
['PASS','PASSWORD','PASSPHRASE','PASSW'],
['RECIPIENT','KEYID','ID','USER','KEYGRIP'],
], @_) if defined $_[0];
$gpgbin ||= which(GPGBIN);
my $tmpdir = File::Temp->newdir(TEMPLATE => 'gpgXXXXX', TMPDIR => 1) unless $gpghome;
if ($gpghome) {
preparedir($gpghome, 0700) or do {
carp(sprintf("Can't prepare dir: %s", $gpghome));
return undef;
};
} else {
$gpghome = $tmpdir->dirname;
}
$gpgconf ||= File::Spec->catfile($gpghome, GPGCONF);
$gpgopts ||= GPGOPTS;
my @opts = ('# Do not edit this file');
if (ref($gpgopts) eq 'ARRAY') { push @opts, @$gpgopts }
else { push @opts, $gpgopts }
fsave($gpgconf, join("\n", @opts)) or do {
carp(sprintf("Can't save GPG conffile: %s", $gpgconf));
return undef;
};
eval { chmod $gpgconf, 0600 };
# Get version
my @cmd = ();
push(@cmd, $gpgbin, "--homedir", $gpghome, "--options", $gpgconf, "--version");
my $err = "";
my $out = execute( [@cmd], undef, \$err, 1 );
my $version = $out && $out =~ /gpg.+?([0-9\.]+)\s*$/m ? $1 : 0;
if ($version) {
my $tv = pack("U*",split(/\./, $version));
unless ($tv gt pack("U*", 2, 0)) {
carp(sprintf("Incorrect GPG version v%vd. Require v2.0.0 and above", $tv));
return undef;
}
}
$out = "" if $version;
# Import keys
foreach my $key ($pubkey, $seckey) {
next unless $key;
next unless length($key);
next unless -e $key;
@cmd = ($gpgbin, "--homedir", $gpghome, "--options", $gpgconf);
push @cmd, "--pinentry-mode", "loopback", "--passphrase", $pass if $pass && length($pass);
push @cmd, "--import", $key;
$out = execute( [@cmd], undef, \$err, 1 );
unless ($recipient) {
foreach my $t ($out, $err) {
next unless $t;
$recipient = $1 if $t =~ /key\s+([a-z0-9]+)\:/im;
last if $recipient;
}
}
}
my $self = bless {
gpgbin => $gpgbin,
homedir => $gpghome,
tempdir => $tmpdir,
gpgconf => $gpgconf,
options => [@opts],
cmd => join(" ", @cmd),
stdout => $out,
stderr => $err,
version => $version,
pubkey => $pubkey,
seckey => $seckey,
password => $pass,
recipient => $recipient,
error => $recipient ? "" : "Incorrect recipient!",
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
$self->{error} = "";
$armor = isTrueFlag($armor);
my $recipient = $self->{recipient};
return 0 unless $recipient;
unless (defined($inf) && length($inf) && -e $inf) {
$self->{error} = sprintf("File not found: %s", $inf // "");
return 0;
}
$outf = sprintf("%s%s", $inf, GPGEXT) unless defined($outf) && length($outf);
my @cmd = ($self->{gpgbin}, "--homedir", $self->{homedir}, "--options", $self->{gpgconf}, "--always-trust");
push(@cmd, "-r", $recipient);
push(@cmd, "-a") if $armor;
push(@cmd, "-o", $outf);
push(@cmd, "-e", $inf);
$self->{cmd} = join(" ", @cmd);
my $err = "";
my $out = execute( [@cmd], undef, \$err, 1 );
$self->{stdout} = $out // '';
$self->{stderr} = $err // '';
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
$self->{error} = "";
unless (defined($inf) && length($inf) && -e $inf) {
$self->{error} = sprintf("File not found: %s", $inf // "");
return 0;
}
unless (defined($outf) && length($outf)) {
$self->{error} = "Incorrect output file";
return 0;
}
my @cmd = ($self->{gpgbin}, "--homedir", $self->{homedir}, "--options", $self->{gpgconf}, "--always-trust");
push(@cmd, "--pinentry-mode", "loopback", "--passphrase", $self->{password}) if $self->{password};
push(@cmd, "-o", $outf);
push(@cmd, "-d", $inf);
$self->{cmd} = join(" ", @cmd);
my $err = "";
my $out = execute( [@cmd], undef, \$err, 1 );
$self->{stdout} = $out // '';
$self->{stderr} = $err // '';
# Return
lib/CTK/Crypt/GPG.pm view on Meta::CPAN
sub error {
my $self = shift;
return $self->{error} // '';
}
1;
__END__
List of keys:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --list-keys
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --list-secret-keys
Delete all keyrings:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --delete-secret-and-public-key 58E79B320D135DEE
Export keys to files:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --export -a -o mypublic.key 58E79B320D135DEE
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --export-secret-keys -a -o myprivate.key 58E79B320D135DEE
Encrypting:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --import ./mypublic.key
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --always-trust -r 58E79B320D135DEE -o README.asc -a -e README
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --delete-keys 58E79B320D135DEE
Decrypting:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --pinentry-mode loopback --passphrase "test" --import ./myprivate.key
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --always-trust --pinentry-mode loopback --passphrase "test" -o README.dec -d README.asc
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --batch --delete-secret-keys 58E79B320D135DEE
Password unset:
gpg --homedir /home/minus/mygpg --options /home/minus/mygpg/gpg.conf --edit-key 58E79B320D135DEE
lib/CTK/Plugin/Crypt.pm view on Meta::CPAN
Version 1.01
=head1 SYNOPSIS
use CTK;
my $ctk = CTK->new(
plugins => "crypt",
);
my $gpg_instance = $ctk->gpg_init(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
$ctk->gpg_encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $self->error );
$ctk->gpg_decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $self->error );
$ctk->tcd_encrypt( "file.txt", "file.tcd" )
or die( $self->error );
$ctk->tcd_decrypt( "file.tcd", "file.txt" )
or die( $self->error );
=head1 DESCRIPTION
Cryptography plugin
See L<https://www.gnupg.org/> (GPG4Win - L<https://www.gpg4win.org/>) for details
=head1 METHODS
=over 8
=item B<gpg_init>
my $gpg_instance = $ctk->gpg_init(
-gpgbin => "/usr/bin/gpg",
-gpghome => "/gpg/homedir",
-gpgconf => "/gpg/homedir/gpg.conf",
-gpgopts => ["verbose", "yes"],
-publickey => "/path/to/public.key",
-privatekey => "/path/to/private.key",
-password => "passphrase", # Key password
-recipient => "anonymous@example.com", # Email, user id, keyid, or keygrip
) or die("Can't create crypter");
Initialize GPG instance. NOTE! It is GLOBAL object!
For using self object please use L<CTK::Crypt::GPG> module
See L<CTK::Crypt::GPG>
=item B<gpg_decrypt>
$ctk->gpg_decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $self->error );
GPG (PGP) Decrypting the files
See L<CTK::Crypt::GPG>
=item B<gpg_encrypt>
$ctk->gpg_encrypt(
-infile => "MyDocument.txt",
-outfile=> "MyDocument.txt.asc",
-armor => "yes",
) or die( $self->error );
GPG (PGP) Encrypting the files
See L<CTK::Crypt::GPG>
=item B<tcd_decrypt>
$ctk->gpg_decrypt(
-infile => "MyDocument.txt.asc",
-outfile=> "MyDocument.txt",
) or die( $self->error );
TCD04 Decrypting the files
See L<CTK::Crypt::TCD04>
=item B<tcd_encrypt>
lib/CTK/Plugin/Crypt.pm view on Meta::CPAN
=head1 TO DO
See C<TODO> file
=head1 BUGS
* none noted
=head1 SEE ALSO
L<CTK>, L<CTK::Plugin>, L<CTK::Crypt>, L<GnuPG|https://www.gnupg.org/>, L<GPG4Win|https://www.gpg4win.org/>
=head1 AUTHOR
Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>
=head1 COPYRIGHT
Copyright (C) 1998-2022 D&D Corporation. All Rights Reserved
=head1 LICENSE
lib/CTK/Plugin/Crypt.pm view on Meta::CPAN
=cut
use vars qw/ $VERSION /;
$VERSION = '1.01';
use base qw/CTK::Plugin/;
use CTK::Crypt ();
__PACKAGE__->register_method(
method => "gpg_init",
callback => sub {
my $self = shift;
return CTK::Crypt::gpg_init(@_);
});
__PACKAGE__->register_method(
method => "gpg_encrypt",
callback => sub {
my $self = shift;
my $status = CTK::Crypt::gpg_encrypt(@_);
return $status if $status;
$self->error($CTK::Crypt::ERROR);
return 0;
});
__PACKAGE__->register_method(
method => "gpg_decrypt",
callback => sub {
my $self = shift;
my $status = CTK::Crypt::gpg_decrypt(@_);
return $status if $status;
$self->error($CTK::Crypt::ERROR);
return 0;
});
__PACKAGE__->register_method(
method => "tcd_encrypt",
callback => sub {
my $self = shift;
my $status = CTK::Crypt::tcd_encrypt(@_);
ok($ctk->conf("flag"), "Flag is true");
is(value($ctk->config(), "myinc/Test/val2"), "Blah-Blah-Blah", "myinc/Test/val2 eq Blah-Blah-Blah");
ok($ctk->configobj->status, "Congig status is ok") or diag($ctk->configobj->error);
if (-d '.svn' || -d '.git') {
note(explain($ctk));
note($ctk->foo);
}
#$ctk->gpg_decript("Blah-Blah-Blah");
1;
__END__
t/19-crypt-gpg.t view on Meta::CPAN
my $dst = File::Spec->catdir("src", "dst");
ok(preparedir($dst), "Prepare $dst");
my $asc_file = File::Spec->catfile($dst, FILENAME_ASC);
my $dec_file = File::Spec->catfile($dst, FILENAME_DEC);
# Create test file with 10 lines
my @pool;
for (1..10) { push @pool, sprintf("%02d %s", $_, randchars( 80 )) };
ok(fsave(FILENAME_SRC, join("\n", @pool)), "Save random file");
my $gpg = new_ok( 'CTK::Crypt::GPG', [(
-publickey => File::Spec->catfile("src", PUBLIC_TEST_KEY),
-privatekey => File::Spec->catfile("src", PRIVATE_TEST_KEY),
-password => PASSWORD,
)] );
exit 1 unless $gpg;
#note(explain($gpg));
# Encrypt file
ok($gpg->encrypt(
-infile => FILENAME_SRC,
-outfile=> $asc_file,
-armor => "yes",
), "Encrypt file") or diag( $gpg->error );
#note(explain($gpg));
# Decrypt file
ok($gpg->decrypt(
-infile => $asc_file,
-outfile=> $dec_file,
), "Decrypt file") or diag( $gpg->error );
is(
Digest::MD5->new->addfile(IO::File->new(FILENAME_SRC, "r"))->hexdigest,
Digest::MD5->new->addfile(IO::File->new($dec_file, "r"))->hexdigest,
"Files are identical"
);
1;
__END__