Added perl module code to the repository.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@81 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2009-04-18 13:47:09 +00:00
parent 7e2d52e38f
commit 58c1a85711
14 changed files with 7193 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
Revision history for Perl extension FKO.
0.22 Sat Apr 18 09:38:32 2009
- First release; works with libfko-1.10.0-alpha.
0.01 Sat Mar 21 22:02:32 2009
- original version; created by h2xs 1.23 with options
-c -n FKO -x ../fko/fko.h -lfko
+452
View File
@@ -0,0 +1,452 @@
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#include <fko.h>
/* Global FKO error code var
*/
int g_ec;
MODULE = FKO PACKAGE = FKO
PROTOTYPES: DISABLE
# This call is used only for the global g_ec error value
# during initialization (in case object instantiation fails).
#
char*
error_str()
CODE:
RETVAL = (char*)fko_errstr(g_ec);
OUTPUT:
RETVAL
#
# All of the remaining functions are wrappers for the
# libfko calls. These are, in turn, wrapped/called from
# the FKO.pm module methods.
#
fko_ctx_t
_init_ctx()
INIT:
fko_ctx_t ctx;
CODE:
g_ec = fko_new(&ctx);
if(g_ec == 0)
RETVAL = ctx;
else
RETVAL = NULL;
OUTPUT:
RETVAL
fko_ctx_t
_init_ctx_with_data(data, key)
INPUT:
char* data;
char* key;
INIT:
fko_ctx_t ctx;
CODE:
g_ec = fko_new_with_data(&ctx, data, key);
if(g_ec == 0)
RETVAL = ctx;
else
RETVAL = NULL;
OUTPUT:
RETVAL
fko_ctx_t
_init_ctx_with_data_only(data)
INPUT:
char* data;
INIT:
fko_ctx_t ctx;
CODE:
g_ec = fko_new_with_data(&ctx, data, NULL);
if(g_ec == 0)
RETVAL = ctx;
else
RETVAL = NULL;
OUTPUT:
RETVAL
void
_destroy_ctx(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
fko_destroy(ctx);
char*
_version(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_version(ctx);
OUTPUT:
RETVAL
char*
_error_str(err_code)
INPUT:
int err_code;
CODE:
RETVAL = fko_errstr(err_code);
OUTPUT:
RETVAL
char*
_gpg_error_str(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_gpg_errorstr(ctx);
OUTPUT:
RETVAL
int
_set_digest_type(ctx, digest_type)
INPUT:
fko_ctx_t ctx;
short digest_type;
CODE:
RETVAL = fko_set_spa_digest_type(ctx, digest_type);
OUTPUT:
RETVAL
short
_get_digest_type(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_digest_type(ctx);
OUTPUT:
RETVAL
int
_set_encryption_type(ctx, encryption_type)
INPUT:
fko_ctx_t ctx;
short encryption_type;
CODE:
RETVAL = fko_set_spa_encryption_type(ctx, encryption_type);
OUTPUT:
RETVAL
short
_get_encryption_type(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_encryption_type(ctx);
OUTPUT:
RETVAL
int
_set_rand_value(ctx, rand_val)
INPUT:
fko_ctx_t ctx;
char* rand_val;
CODE:
RETVAL = fko_set_rand_value(ctx, rand_val);
OUTPUT:
RETVAL
char*
_get_rand_value(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_rand_value(ctx);
OUTPUT:
RETVAL
int
_set_username(ctx, username)
INPUT:
fko_ctx_t ctx;
char* username;
CODE:
RETVAL = fko_set_username(ctx, username);
OUTPUT:
RETVAL
char*
_get_username(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_username(ctx);
OUTPUT:
RETVAL
int
_set_spa_message_type(ctx, spa_message_type)
INPUT:
fko_ctx_t ctx;
int spa_message_type;
CODE:
RETVAL = fko_set_spa_message_type(ctx, spa_message_type);
OUTPUT:
RETVAL
short
_get_spa_message_type(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_message_type(ctx);
OUTPUT:
RETVAL
int
_set_timestamp(ctx, offset)
INPUT:
fko_ctx_t ctx;
int offset;
CODE:
RETVAL = fko_set_timestamp(ctx, offset);
OUTPUT:
RETVAL
unsigned int
_get_timestamp(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_timestamp(ctx);
OUTPUT:
RETVAL
int
_set_spa_message(ctx, spa_message)
INPUT:
fko_ctx_t ctx;
char* spa_message;
CODE:
RETVAL = fko_set_spa_message(ctx, spa_message);
OUTPUT:
RETVAL
char*
_get_spa_message(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_message(ctx);
OUTPUT:
RETVAL
int
_set_spa_nat_access(ctx, spa_nat_access)
INPUT:
fko_ctx_t ctx;
char* spa_nat_access;
CODE:
RETVAL = fko_set_spa_nat_access(ctx, spa_nat_access);
OUTPUT:
RETVAL
char*
_get_spa_nat_access(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_nat_access(ctx);
OUTPUT:
RETVAL
int
_set_spa_server_auth(ctx, spa_server_auth)
INPUT:
fko_ctx_t ctx;
char* spa_server_auth;
CODE:
RETVAL = fko_set_spa_server_auth(ctx, spa_server_auth);
OUTPUT:
RETVAL
char*
_get_spa_server_auth(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_server_auth(ctx);
OUTPUT:
RETVAL
int
_set_spa_client_timeout(ctx, spa_client_timeout)
INPUT:
fko_ctx_t ctx;
int spa_client_timeout;
CODE:
RETVAL = fko_set_spa_client_timeout(ctx, spa_client_timeout);
OUTPUT:
RETVAL
int
_get_spa_client_timeout(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_client_timeout(ctx);
OUTPUT:
RETVAL
int
_set_spa_digest(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_set_spa_digest(ctx);
OUTPUT:
RETVAL
char*
_get_spa_digest(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_digest(ctx);
OUTPUT:
RETVAL
int
_set_spa_data(ctx, spa_data)
INPUT:
fko_ctx_t ctx;
char* spa_data;
CODE:
RETVAL = fko_set_spa_data(ctx, spa_data);
OUTPUT:
RETVAL
char*
_get_spa_data(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_spa_data(ctx);
OUTPUT:
RETVAL
int
_set_gpg_recipient(ctx, gpg_recipient)
INPUT:
fko_ctx_t ctx;
char* gpg_recipient;
CODE:
RETVAL = fko_set_gpg_recipient(ctx, gpg_recipient);
OUTPUT:
RETVAL
char*
_get_gpg_recipient(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_gpg_recipient(ctx);
OUTPUT:
RETVAL
int
_set_gpg_signer(ctx, gpg_signer)
INPUT:
fko_ctx_t ctx;
char* gpg_signer;
CODE:
RETVAL = fko_set_gpg_signer(ctx, gpg_signer);
OUTPUT:
RETVAL
char*
_get_gpg_signer(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_gpg_signer(ctx);
OUTPUT:
RETVAL
int
_set_gpg_home_dir(ctx, gpg_home_dir)
INPUT:
fko_ctx_t ctx;
char* gpg_home_dir;
CODE:
RETVAL = fko_set_gpg_home_dir(ctx, gpg_home_dir);
OUTPUT:
RETVAL
char*
_get_gpg_home_dir(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_gpg_home_dir(ctx);
OUTPUT:
RETVAL
char*
_get_encoded_data(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_get_encoded_data(ctx);
OUTPUT:
RETVAL
int
_spa_data_final(ctx, enc_key)
INPUT:
fko_ctx_t ctx;
char* enc_key;
CODE:
RETVAL = fko_spa_data_final(ctx, enc_key);
OUTPUT:
RETVAL
int
_decrypt_spa_data(ctx, dec_key)
INPUT:
fko_ctx_t ctx;
char* dec_key;
CODE:
RETVAL = fko_decrypt_spa_data(ctx, dec_key);
OUTPUT:
RETVAL
int
_encrypt_spa_data(ctx, enc_key)
INPUT:
fko_ctx_t ctx;
char* enc_key;
CODE:
RETVAL = fko_encrypt_spa_data(ctx, enc_key);
OUTPUT:
RETVAL
int
_decode_spa_data(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_decode_spa_data(ctx);
OUTPUT:
RETVAL
int
_encode_spa_data(ctx)
INPUT:
fko_ctx_t ctx;
CODE:
RETVAL = fko_encode_spa_data(ctx);
OUTPUT:
RETVAL
###EOF###
+14
View File
@@ -0,0 +1,14 @@
Changes
FKO.xs
Makefile.PL
MANIFEST
ppport.h
README
typemap
t/00_init.t
t/01_constants.t
t/02_functions.t
t/03_errors.t
lib/FKO.pm
lib/FKO_Constants.pl
inc/Devel/CheckLib.pm
+38
View File
@@ -0,0 +1,38 @@
use lib 'inc';
use Devel::CheckLib;
use 5.008008;
use ExtUtils::MakeMaker;
my $fkolib_dir;
my @libdirs = qw(
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/usr/lib64/fko
/usr/lib/fko
/usr/local/lib64/fko
/usr/local/lib/fko
/opt/fko/lib64
/opt/fko/lib
);
check_lib_or_exit(
lib => [qw( fko )],
libpath => \@libdirs
);
WriteMakefile(
NAME => 'FKO',
VERSION_FROM => 'lib/FKO.pm',
PREREQ_PM => {},
($] >= 5.005 ?
(ABSTRACT_FROM => 'lib/FKO.pm',
AUTHOR => 'Damien S. Stuart <dstuart@dstuart.org>') : ()),
LIBS => ['-lfko'],
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-I.',
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too
);
+31
View File
@@ -0,0 +1,31 @@
FKO version 0.10
================
This module is essentially a Perl wrapper for the Firewall Knock
Operator library, "libfko". See the "libfko" documentation for
additional information on the functionality provided by "libfko"
and usage overview.
INSTALLATION
To install this module type the following:
perl Makefile.PL
make
make test
make install
DEPENDENCIES
This module requires these other modules and libraries:
The Firewall Knock Operator library, "libfko".
COPYRIGHT AND LICENCE
Copyright (C) 2009 by Damien S. Stuart <dstuart@dstuart.org>
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
+278
View File
@@ -0,0 +1,278 @@
# $Id: CheckLib.pm,v 1.10 2007/10/30 15:12:17 drhyde Exp $
package Devel::CheckLib;
use strict;
use vars qw($VERSION @ISA @EXPORT);
$VERSION = '0.3';
use Config;
use File::Spec;
use File::Temp;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(assert_lib check_lib_or_exit);
# localising prevents the warningness leaking out of this module
local $^W = 1; # use warnings is a 5.6-ism
_findcc(); # bomb out early if there's no compiler
=head1 NAME
Devel::CheckLib - check that a library is available
=head1 DESCRIPTION
Devel::CheckLib is a perl module that checks whether a particular C
library is available, and dies if it is not.
=head1 SYNOPSIS
# in a Makefile.PL or Build.PL
use lib qw(inc);
use Devel::CheckLib;
check_lib_or_exit( lib => 'jpeg' );
check_lib_or_exit( lib => [ 'iconv', 'jpeg' ] );
# or prompt for path to library and then do this:
check_lib_or_exit( lib => 'jpeg', libpath => $additional_path );
=head1 HOW IT WORKS
You pass named parameters to a function
describing how to build and link to the library. Currently the only
parameter supported is 'lib', which can be a string or an arrayref of
several libraries. In the future, expect us to add something for
checking that header files are available as well.
It works by trying to compile this:
int main(void) { return 0; }
and linking it to the specified libraries. If something pops out the end
which looks executable, then we know that it worked.
=head1 FUNCTIONS
All of these take the same named parameters and are exported by default.
To avoid exporting them, C<use Devel::CheckLib ()>.
=head2 assert_lib
Takes several named parameters.
The value of C<lib> must be either a string with the name of a single
library or a reference to an array of strings of library names. Depending
on the compiler found, library names will be fed to the compiler either as
C<-l> arguments or as C<.lib> file names. (E.g. C<-ljpeg> or C<jpeg.lib>)
Likewise, C<libpath> must if provided either be a string or an array of strings
representing additional paths to search for libraries.
C<LIBS> must be a C<ExtUtils::MakeMaker>-style space-seperated list of
libraries (each preceded by '-l') and directories (preceded by '-L').
This will die with an error message if any of the libraries listed can
not be found. B<Note>: dying in a Makefile.PL or Build.PL may provoke
a 'FAIL' report from CPAN Testers' automated smoke testers. Use
C<check_lib_or_exit> instead.
=head2 check_lib_or_exit
This behaves exactly the same as C<assert_lib()> except that instead of
dieing, it warns (with exactly the same error message) and exits.
This is intended for use in Makefile.PL / Build.PL
when you might want to prompt the user for various paths and
things before checking that what they've told you is sane.
If a library isn't found, it exits with an exit value of 0 to avoid
causing a CPAN Testers 'FAIL' report. CPAN Testers should ignore this
result -- which is what you want if an external library dependency is not
available.
=cut
sub check_lib_or_exit {
eval 'assert_lib(@_)';
if($@) {
warn $@;
exit;
}
}
sub assert_lib {
my %args = @_;
my (@libs, @libpaths);
@libs = (ref($args{lib}) ? @{$args{lib}} : $args{lib})
if $args{lib};
@libpaths = (ref($args{libpath}) ? @{$args{libpath}} : $args{libpath})
if $args{libpath};
# work-a-like for Makefile.PL's "LIBS" argument
if(defined($args{LIBS})) {
foreach my $arg (split(/\s+/, $args{LIBS})) {
die("LIBS argument badly-formed: $arg\n") unless($arg =~ /^-l/i);
push @{$arg =~ /^-l/ ? \@libs : \@libpaths}, substr($arg, 2);
}
}
my @cc = _findcc();
my($ch, $cfile) = File::Temp::tempfile(
'assertlibXXXXXXXX', SUFFIX => '.c', UNLINK => 1
);
print $ch "int main(void) { return 0; }\n";
close($ch);
my @missing;
for my $lib ( @libs ) {
my $exefile = File::Temp::mktemp( 'assertlibXXXXXXXX' ) . $Config{_exe};
my @sys_cmd;
if ( $Config{cc} eq 'cl' ) { # Microsoft compiler
require Win32;
my @libpath = map {
q{/libpath:} . Win32::GetShortPathName($_)
} @libpaths;
@sys_cmd = (@cc, $cfile, "${lib}.lib", "/Fe$exefile",
"/link", @libpath
);
} elsif($Config{cc} =~ /bcc32(\.exe)?/) { # Borland
my @libpath = map { "-L$_" } @libpaths;
@sys_cmd = (@cc, "-o$exefile", "-l$lib", @libpath, $cfile);
} else { # Unix-ish
# gcc, Sun, AIX (gcc, cc)
my @libpath = map { "-L$_" } @libpaths;
@sys_cmd = (@cc, $cfile, "-o", "$exefile", "-l$lib", @libpath);
}
warn "# @sys_cmd\n" if $args{debug};
my $rv = $args{debug} ? system(@sys_cmd) : _quiet_system(@sys_cmd);
push @missing, $lib if $rv != 0 || ! -x $exefile;
_cleanup_exe($exefile);
}
unlink $cfile;
my $miss_string = join( q{, }, map { qq{'$_'} } @missing );
die("Can't build and link to $miss_string\n") if @missing;
}
sub _cleanup_exe {
my ($exefile) = @_;
my $ofile = $exefile;
$ofile =~ s/$Config{_exe}$/$Config{_o}/;
unlink $exefile if -f $exefile;
unlink $ofile if -f $ofile;
unlink "$exefile\.manifest" if -f "$exefile\.manifest";
return
}
sub _findcc {
my @paths = split(/$Config{path_sep}/, $ENV{PATH});
my @cc = split(/\s+/, $Config{cc});
return @cc if -x $cc[0];
foreach my $path (@paths) {
my $compiler = File::Spec->catfile($path, $cc[0]) . $Config{_exe};
return ($compiler, @cc[1 .. $#cc]) if -x $compiler;
}
die("Couldn't find your C compiler\n");
}
# code substantially borrowed from IPC::Run3
sub _quiet_system {
my (@cmd) = @_;
# save handles
local *STDOUT_SAVE;
local *STDERR_SAVE;
open STDOUT_SAVE, ">&STDOUT" or die "CheckLib: $! saving STDOUT";
open STDERR_SAVE, ">&STDERR" or die "CheckLib: $! saving STDERR";
# redirect to nowhere
local *DEV_NULL;
open DEV_NULL, ">" . File::Spec->devnull
or die "CheckLib: $! opening handle to null device";
open STDOUT, ">&" . fileno DEV_NULL
or die "CheckLib: $! redirecting STDOUT to null handle";
open STDERR, ">&" . fileno DEV_NULL
or die "CheckLib: $! redirecting STDERR to null handle";
# run system command
my $rv = system(@cmd);
# restore handles
open STDOUT, ">&" . fileno STDOUT_SAVE
or die "CheckLib: $! restoring STDOUT handle";
open STDERR, ">&" . fileno STDERR_SAVE
or die "CheckLib: $! restoring STDERR handle";
return $rv;
}
=head1 PLATFORMS SUPPORTED
You must have a C compiler installed. We check for C<$Config{cc}>,
both literally as it is in Config.pm and also in the $PATH.
It has been tested with varying degrees on rigourousness on:
=over
=item gcc (on Linux, *BSD, Solaris, Cygwin)
=item Sun's compiler tools on Solaris
=item IBM's tools on AIX
=item Microsoft's tools on Windows
=item MinGW on Windows (with Strawberry Perl)
=item Borland's tools on Windows
=back
=head1 WARNINGS, BUGS and FEEDBACK
This is a very early release intended primarily for feedback from
people who have discussed it. The interface may change and it has
not been adequately tested.
Feedback is most welcome, including constructive criticism.
Bug reports should be made using L<http://rt.cpan.org/> or by email.
When submitting a bug report, please include the output from running:
perl -V
perl -MDevel::CheckLib
=head1 SEE ALSO
L<Devel::CheckOS>
=head1 AUTHORS
David Cantrell E<lt>david@cantrell.org.ukE<gt>
David Golden E<lt>dagolden@cpan.orgE<gt>
Thanks to the cpan-testers-discuss mailing list for prompting us to write it
in the first place;
to Chris Williams for help with Borland support.
=head1 COPYRIGHT and LICENCE
Copyright 2007 David Cantrell. Portions copyright 2007 David Golden.
This module is free-as-in-speech software, and may be used, distributed,
and modified under the same conditions as perl itself.
=head1 CONSPIRACY
This module is also free-as-in-mason software.
=cut
1;
+843
View File
@@ -0,0 +1,843 @@
##############################################################################
#
# File: FKO.pm
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: The Firewall Knock Operator library (libfko) Perl module.
#
##############################################################################
#
package FKO;
use 5.008008;
use strict;
use warnings;
use Carp;
require Exporter;
our $VERSION = '0.21';
our @ISA = qw(Exporter);
# Our export tag arrays. These are defined in FKO_Constants.pl
#
our (
@MSG_TYPES,
@DIGEST_TYPES,
@ENCRYPTION_TYPES,
@ERROR_CODES
);
# This holds the constants definitions and tag arrays.
#
require "FKO_Constants.pl";
our %EXPORT_TAGS = (
'message_types' => \@MSG_TYPES,
'encryption_types' => \@ENCRYPTION_TYPES,
'errors' => \@ERROR_CODES,
'types' => [
@MSG_TYPES,
@ENCRYPTION_TYPES
],
'all' => [
@MSG_TYPES,
@DIGEST_TYPES,
@ENCRYPTION_TYPES,
@ERROR_CODES
]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our $error_str;
require XSLoader;
XSLoader::load('FKO', $VERSION);
##############################################################################
# Constructor.
#
sub new {
my $class = shift;
my $data = shift;
my $dc_pw = shift;
my $res;
my $ctx;
# If data was passed, call _init_ctx_with_data. If a password was
# not defined, then pass 0.
#
if($data) {
if(defined($dc_pw)) {
$ctx = _init_ctx_with_data($data, $dc_pw);
} else {
$ctx = _init_ctx_with_data_only($data);
}
} else {
$ctx = _init_ctx();
}
unless($ctx) {
my $errstr = FKO::error_str();
$error_str = "Unable initialize FKO context: $errstr\n";
return undef;
}
bless {
_ctx => $ctx # Gotta hang on to our context...
}, $class;
}
# The following methods wrap the libfko C functions. Most of the get/set
# functions are rolled into a single method here such that if an argument
# is passed, it will set (and return) the value. Otherwise, the current
# value is returned.
sub destroy {
my $self = shift;
return unless($self->{_ctx});
FKO::_destroy_ctx($self->{_ctx});
$self->{_ctx} = undef;
}
sub version {
my $self = shift;
return FKO::_version($self->{_ctx});
}
sub errstr {
my $self = shift;
my $ec = shift || 0;
return FKO::_error_str($ec);
}
sub gpg_errstr {
my $self = shift;
return FKO::_gpg_error_str($self->{_ctx});
}
sub rand_value {
my $self = shift;
my $newval = shift;
return FKO::_set_rand_value($self->{_ctx}, $newval || 0)
if(defined($newval));
return FKO::_get_rand_value($self->{_ctx});
}
sub digest_type {
my $self = shift;
my $newval = shift;
return FKO::_set_digest_type($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_digest_type($self->{_ctx});
}
sub encryption_type {
my $self = shift;
my $newval = shift;
return FKO::_set_encryption_type($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_encryption_type($self->{_ctx});
}
sub username {
my $self = shift;
my $newval = shift;
return FKO::_set_username($self->{_ctx}, $newval || 0)
if(defined($newval));
return FKO::_get_username($self->{_ctx});
}
sub spa_message_type {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_message_type($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_message_type($self->{_ctx});
}
sub timestamp {
my $self = shift;
my $newval = shift;
return FKO::_set_timestamp($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_timestamp($self->{_ctx});
}
sub spa_message {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_message($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_message($self->{_ctx});
}
sub spa_nat_access {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_nat_access($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_nat_access($self->{_ctx});
}
sub spa_server_auth {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_server_auth($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_server_auth($self->{_ctx});
}
sub spa_client_timeout {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_client_timeout($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_client_timeout($self->{_ctx});
}
sub spa_digest {
my $self = shift;
my $recompute = shift || 0;
return FKO::_set_spa_digest($self->{_ctx})
if($recompute);
return FKO::_get_spa_digest($self->{_ctx});
}
sub spa_data {
my $self = shift;
my $newval = shift;
return FKO::_set_spa_data($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_spa_data($self->{_ctx});
}
sub gpg_recipient {
my $self = shift;
my $newval = shift;
return FKO::_set_gpg_recipient($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_gpg_recipient($self->{_ctx});
}
sub gpg_signer {
my $self = shift;
my $newval = shift;
return FKO::_set_gpg_signer($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_gpg_signer($self->{_ctx});
}
sub gpg_home_dir {
my $self = shift;
my $newval = shift;
return FKO::_set_gpg_home_dir($self->{_ctx}, $newval)
if(defined($newval));
return FKO::_get_gpg_home_dir($self->{_ctx});
}
sub encoded_data {
my $self = shift;
return FKO::_get_encoded_data($self->{_ctx});
}
sub spa_data_final {
my $self = shift;
my $key = shift || '';
return FKO::_spa_data_final($self->{_ctx}, $key)
}
sub encrypt_spa_data {
my $self = shift;
my $key = shift || '';
return FKO::_encrypt_spa_data($self->{_ctx}, $key)
}
sub decrypt_spa_data {
my $self = shift;
my $key = shift || '';
return FKO::_decrypt_spa_data($self->{_ctx}, $key)
}
sub encode_spa_data {
my $self = shift;
return FKO::_encode_spa_data($self->{_ctx});
}
sub decode_spa_data {
my $self = shift;
return FKO::_decode_spa_data($self->{_ctx});
}
sub DESTROY {
my $self = shift;
FKO::_destroy_ctx($self->{_ctx}) if($self->{_ctx});
}
1;
__END__
=head1 NAME
FKO - Perl module wrapper for libfko
=head1 SYNOPSIS
use FKO;
# Create a new empty FKO object.
#
my $fko = FKO->new();
if(!$fko) {
die "Unable to create FKO object: $FKO::error_str\n");
}
# Override the username (default is current user).
#
my $err = $fko->username('joeuser');
if($err) {
die "Error setting username: ", $fko->errstr($err), "\n";
}
# Set the SPA message (see libfko docs for details).
#
$err = $fko->spa_message('0.0.0.0,tcp/22');
# ..error checking, etc...
$err = $fko->spa_data_final();
# ..error checking, etc...
# Get the encrypted and encoded SPA data.
#
my $spa_data = $fko->spa_data();
## Incoming SPA data ##
# Create an FKO object to process incoming (or existing)
# SPA data.
#
my $fko_in = FKO->new($enc_spa_data, 'decrypt_pw')
or die "Unable to create FKO object: $FKO::error_str\n";
my $timestamp = $fko_in->timestamp();
my $fko_user = $fko_in->username();
my $spa_msg = $fko_in->spa_message();
my $digest = $fko_in->spa_digest();
# Pull the digest type.
my $digest_type = $fko_in->spa_digest_type();
if($digest_type == FKO::FKO_DIGEST_SHA256) {
# do something
} elsif($digest_type == FKO::FKO_DIGEST_MD5) {
# do something else
}
=head1 DESCRIPTION
This module is essentially a Perl wrapper for the I<Firewall Knock Operator>
(fwknop) library, C<libfko>. Fwknop is an open source implementation of
I<Single Packet Authorization> (I<SPA>) for access to networked resources.
The original I<fwknop> is implemented in Perl. The I<libfko> library is
an implementation of the I<fwknop> back-end data processing routines written
in C as part of the project to move all of I<fwknop> to C.
See the C<libfko> documentation for additional information on usage and the
functionality provided by C<libfko>. More information on I<SPA> and I<fwknop>
can be found at http://www.cipherdine.org/fwknop.
=head1 CONSTRUCTOR
=over
=item B<new( )>
=item B<new($spa_data, $password)>
The C<new> method creates the I<FKO> object. With no arguments, it creates
creates and empty I<FKO> object ready to be popluated with data (i.e. create
a new SPA data packet to send).
You can also pass existing encoded/encrypted I<SPA> data and a decryption
password to C<new>. Passing valid data and a password will create the new
object, decode and parse the data, and store it within the object for later
retrieval using the various methods described below.
If there are any errors during the creation or decoding of the data I<new>
will return undef and the appropriate error message will be available in the
C<$FKO::error_str> variable.
Create an empty object:
my $fko = FKO->new();
Create an object using existing data:
my $fko = FKO->new($spa_data, 'decrypt_pw');
=back
=head1 METHODS
=head2 Utility Methods
The utility methods are those that perform the non-data-set/get functions
like error messages, data processing, and clean-up.
=over
=item B<destroy( )>
The C<destroy> method is used when you are done with the I<FKO> object and its
data. This method will make the appropriate I<libfko> calls to clean-up and
release resources used by the object.
Though C<destroy> will be called if the object goes out of scope, it is good
practice to clean up after yourself. This is especially true if you are
processing multiple I<SPA> messages in a loop, etc.
=item B<errstr($err_code)>
This method returns the descriptive error message string for the given
error code value.
=item B<gpg_errstr( )>
If the previous I<FKO> error was from a GPG-related function, then calling
this method may return more detailed information from the GPG error handling
system.
=item B<spa_data_final( )>
This function is the final step in creating a complete encrypted I<SPA> data
string suitable for transmission to an fwknop server. It does require all
of the requisite I<SPA> data fields be set. Otherwise it will fail and
return the appropriate error code.
=item B<encrypt_spa_data( )>
Encrypts the intermediate encoded I<SPA> data stored in the context. The
internal I<libfko> encryption function will call the internal
C<encode_spa_data> if necessary.
This function is normally not called directly as it is automatically called
from the internal C<fko_spa_data_final> function (which is wrapped by this
module's C<spa_data_final> function.
=item B<decrypt_spa_data( )>
When given the correct I<key> (passsword), this function decrypts, decodes,
and parses the encrypted I<SPA> data contained in the current context.
Once the data is decrypted, the I<libfko> internal function will also call
the I<libfko> decode function to decode, parse, validate, and store the data
fields in the context for later retrieval.
Note: This function does not need to be called directly if encrypted I<SPA>
data was passed to this module's constructor when the object was created as
the C<new> function will call decrypt and decode itself.
=item B<encode_spa_data( )>
Instructs I<libfko> to perform the base64 encoding of those I<SPA> data
fields that need to be encoded, perform some data validation, compute and
store the message digest hash for the I<SPA> data.
This function is normally not called directly as it is called by other
I<libfko> functions during normal processing (i.e during encypt and/or final
functions.
=item B<decode_spa_data( )>
This function hands of the data to the I<libfko> decoding routines which
perform the decoding, parsing, and validation of the I<SPA> data that was
just decrypted.
This function is normally not called directly as it is called by other
I<libfko> functions during normal processing.
=back
=head2 Working with SPA Data Types
There are a few data and method types supported by I<libfko>, along with a
few functions for getting and setting them. Most of these I<types> are
represented using constants defined in the I<FKO> module.
=over
=item B<encryption_type( )>
=item B<encryption_type(FKO_ENCRYPTION_TYPE)>
Get or set the encryption type for the current context. If no argument is
given, the current value is returned. Otherwise encryption type will be set
to the given value.
The encryption type parameter is an integer value. Constants have been
defined to represent this values. Currently, the only supported encryption
types are:
=over
=item * B<FKO_ENCRYPTION_RIJNDAEL>
The default I<libfko> encryption algorithm.
=item * B<FKO_ENCRYPTION_GPG>
GnuPG encryption (if supported by the underlying I<libfko> implementation).
=back
=item B<digest_type( )>
=item B<digest_type(FKO_DIGEST_TYPE)>
Get or set the digest type for the current context. If no argument is
given, the current value is returned. Otherwise digest type will be set
to the given value.
The digest type parameter is an integer value. Constants have been
defined to represent this values. Currently, the supported digest
types are:
=over
=item * B<FKO_DIGEST_MD5>
The MD5 message digest algorithm.
=item * B<FKO_DIGEST_SHA1>
The SHA1 message digest algorithm.
=item * B<FKO_DIGEST_SHA256>
The SHA256 message digest algorithm. This is the I<libfko> default.
=back
=item B<spa_message_type( )>
=item B<spa_message_type(FKO_MSG_TYPE)>
Get or set the I<SPA> message type. If no argument is given, the current
value is returned. Otherwise message type will be set to the given value.
The message type parameter is an integer value. Constants have been
defined to represent this values. Currently, the supported digest
types are:
=over
=item * B<FKO_COMMAND_MSG>
A request to have the fwknop server execute the given command. The format
for this type is: C<< <ip of requestor>:<command text> >>
For example:
"192.168.1.2:uname -a"
=item * B<FKO_ACCESS_MSG>
A basic access request. This is the most common type in use. The format
for this type is: C<< <ip of requestor>:<protocol>/<port> >>.
For example:
"192.168.1.2:tcp/22"
=item * B<FKO_NAT_ACCESS_MSG>
An access request that also provide information for the fwknop server to
create a Network Address Translation (NAT to an internal address. The format
for this string is: C<< <internal ip>,<ext nat port> >>.
For example:
"10.10.1.2,9922"
=item * B<FKO_CLIENT_TIMEOUT_ACCESS_MSG>
This is an C<FKO_ACCESS_REQUEST> with a timeout parameter for the fwknop
server. The timeout value is provided via the C<client_timeout> data field.
=item * B<FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG>
This is an C<FKO_NAT_ACCESS_REQUEST> with a timeout parameter for the fwknop
server. The timeout value is provided via the C<client_timeout> data field.
=item * B<FKO_LOCAL_NAT_ACCESS_MSG>
This is similar to the C<FKO_NAT_ACCESS> request exept the NAT is to the
local to the server (i.e. a service listening on 127.0.0.1).
=item * B<FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCES_MSG>
This is an C<FKO_LOCAL_NAT_ACCESS_REQUEST> with a timeout parameter for the
fwknop server. The timeout value is provided via the C<client_timeout> data
field.
=back
=back
=head2 Working With SPA Data
The I<SPA> data methods are used for setting or retrieving the various I<SPA>
data field values. Some of these simply return a read-only value, while
others are used to set or get values.
B<Note:> The following methods are presented roughly in the order their
respective data values appear in an I<fwknop> I<SPA> message. Many of these
have reasonable default values at creation and are not typically used in
most circumstances.
=over
=item B<rand_value( )>
=item B<rand_value($new_value)>
Get or set the random value portion of the I<SPA> data. If setting the
random value, you must pass either a 16-character decimal number (to
set it to the given number), or the value C<0> to have a new random value
generated by I<libfko>.
If a provided value is not a valid 16-character decimal string, the function
will return the C<FKO_ERROR_INVALID_DATA> error code.
Upon creation of a new I<FKO> object, this value is automatically generated.
=item B<username( )>
=item B<username($username)>
Set or get the username field of the I<SPA> data. If no argument is given,
given, this function will return the current value. Otherwise, the username
value will be set to the name provided.
If a value of C<0> is given, I<libfko> will attempt to determine and set the
username by first looking for the environment variable C<SPOOF_USER> and use
its value if found. Otherwise, it will try to determine the username
itself using various system methods, then fallback to the environment
variables C<LOGNAME> or C<USER>. If none of those work, the function will
return the C<FKO_ERROR_USERNAME_UNKNOWN> error code.
Upon creation of a new I<FKO> object, this value is automatically generated
based on the I<libfko> method described above.
=item B<timestamp( )>
=item B<timestamp($offset)>
Gets or sets the timestamp value of the SPA data. If no argument is given,
the current value is returned.
If an argument is provided, it will represent an offset to be applied to the
current timestamp value at the time this function was called.
Upon creation of a new I<FKO> object, this value is automatically generated
based on the time of object creation.
=item B<version( )>
Returns the I<fwknop> version string. This version represents the supported
I<fwknop> I<SPA> message format and features. This has nothing to do with
the version of this module.
=item B<spa_message( )>
=item B<spa_message($spa_msg)>
Get or set the I<SPA> message string. If no argument is given, the current
value is returned. Otherwise I<SPA> message string will be set to the given
value.
=item B<spa_nat_access( )>
=item B<spa_nat_access($nat_access)>
Get or set the I<SPA> nat access string. If no argument is given, the
current value is returned. Otherwise I<SPA> nat access string will be set
to the given value.
=item B<spa_server_auth( )>
=item B<spa_server_auth($server_auth)>
Get or set the I<SPA> server auth string. If no argument is given, the
current value is returned. Otherwise I<SPA> server auth string will be set
to the given value.
=item B<spa_client_timeout( )>
=item B<spa_client_timeout($new_timeout)>
Get or set the I<SPA> message client timeout value. This is an integer
value. If no argument is given, the current value is returned. Otherwise
I<SPA> message client timeout value will be set to the given value.
=item B<spa_digest( )>
=item B<spa_digest(1)>
When called with no argument, the C<spa_digest> function returns the digest
associated with the current data (if available). If a true value (i.e. C<1>)
is given as the argument, it will force a recompute of the digest based on
the data and the configured I<digest_type>.
This function is normally not called directly as it is called by other
I<libfko> functions during normal processing.
=item B<encoded_data( )>
Returns the encoded I<SPA> data as it would be just before the encryption
step. This is not generally useful unless you are debugging a data issue.
=item B<spa_data( )>
=item B<spa_data($spa_data)>
Get or set the I<SPA> data string. If no argument is given, the current
value is returned. This would be the final encrypted and encoded string
of data that is suitable for sending to an I<fwkno> server.
If an argument is given, it is expected to be an existing encrypted and
encoded I<SPA> data string (perhaps data received by an I<fwknop> server).
The provided data is stored in the object (the current context).
Note: When data is provided via this function, it is not automatically
decoded. You would need to call C<decrypt_spa_data($pw)> to complete the
decryption, decoding, and parsing process.
=item B<gpg_recipient( )>
=item B<gpg_recipient($gpg_id)>
Get or set the gpg_recipient. This is the ID or email of the public GPG key
of the intended recipient. In order for this function to work, the following
condition must be met:
=over
=item * The underlying I<libfko> implementation nust have GPG support.
=item * The I<encryption_type> must be set to C<FKO_ENCRYPTION_GPG>.
=item * The specified GPG key must exist and be valid.
=back
If no argument is given, the current value is returned. Otherwise,
gpg_recipient will be set to the given value.
=item B<gps_signer( )>
=item B<gps_signer($gpg_id)>
Get or set the gpg_signer. This is the ID or email for the secret GPG key
to be used to sign the encryped data. In order for this function to work,
the following condition must be met:
=over
=item * The underlying I<libfko> implementation nust have GPG support.
=item * The I<encryption_type> must be set to C<FKO_ENCRYPTION_GPG>.
=item * The specified GPG key must exist and be valid.
=back
If no argument is given, the current value is returned. Otherwise,
gpg_recipient will be set to the given value.
=item B<gpg_home_dir( )>
=item B<gpg_home_dir($new_dir)>
Get or set the GPG home directory. This is the directory that holds the
GPG keyrings, etc. In order for this function to work, the following
condition must be met:
=over
=item * The underlying I<libfko> implementation nust have GPG support.
=item * The I<encryption_type> must be set to C<FKO_ENCRYPTION_GPG>.
=item * The specified GPG home directory must exist.
=back
If no argument is given, the current value is returned. Otherwise,
gpg_recipient will be set to the given value.
=head1 SEE ALSO
L<Perl>, the C<libfko> manual.
Additional information on the Firewall Knock Operater (I<fwknop>) can
be found at http://www.cipherdyne.org/fwknop.
=head1 AUTHOR
Damien S. Stuart, E<lt>dstuart@dstuart.orgE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2009 by Damien S. Stuart
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.8 or,
at your option, any later version of Perl 5 you may have available.
=cut
###EOF###
+153
View File
@@ -0,0 +1,153 @@
##############################################################################
#
# File: FKO_Constants.pl
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Constants for the FKO module.
#
##############################################################################
#
# Message types tag list.
#
our @MSG_TYPES = qw(
FKO_COMMAND_MSG
FKO_ACCESS_MSG
FKO_NAT_ACCESS_MSG
FKO_CLIENT_TIMEOUT_ACCESS_MSG
FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG
FKO_LOCAL_NAT_ACCESS_MSG
FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG
);
# Digest types tag list.
#
our @DIGEST_TYPES = qw(
FKO_DIGEST_MD5
FKO_DIGEST_SHA1
FKO_DIGEST_SHA256
);
# Encryption types tag list.
#
our @ENCRYPTION_TYPES = qw(
FKO_ENCRYPTION_RIJNDAEL
FKO_ENCRYPTION_GPG
);
# Error codes tag list.
#
our @ERROR_CODES = qw(
FKO_SUCCESS
FKO_ERROR_CTX_NOT_INITIALIZED
FKO_ERROR_MEMORY_ALLOCATION
FKO_ERROR_INVALID_DATA
FKO_ERROR_DATA_TOO_LARGE
FKO_ERROR_USERNAME_UNKNOWN
FKO_ERROR_INCOMPLETE_SPA_DATA
FKO_ERROR_MISSING_ENCODED_DATA
FKO_ERROR_INVALID_DIGEST_TYPE
FKO_ERROR_INVALID_ALLOW_IP
FKO_ERROR_INVALID_SPA_COMMAND_MSG
FKO_ERROR_INVALID_SPA_ACCESS_MSG
FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG
FKO_ERROR_INVALID_ENCRYPTION_TYPE
FKO_ERROR_WRONG_ENCRYPTION_TYPE
FKO_ERROR_DECRYPTION_SIZE
FKO_ERROR_DECRYPTION_FAILURE
FKO_ERROR_DIGEST_VERIFICATION_FAILED
FKO_ERROR_UNSUPPORTED_FEATURE
FKO_ERROR_UNKNOWN
GPGME_ERR_START
FKO_ERROR_MISSING_GPG_KEY_DATA
FKO_ERROR_GPGME_NO_OPENPGP
FKO_ERROR_GPGME_CONTEXT
FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ
FKO_ERROR_GPGME_SET_PROTOCOL
FKO_ERROR_GPGME_CIPHER_DATA_OBJ
FKO_ERROR_GPGME_BAD_PASSPHRASE
FKO_ERROR_GPGME_ENCRYPT_SIGN
FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY
FKO_ERROR_GPGME_SIGNER_KEYLIST_START
FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND
FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS
FKO_ERROR_GPGME_ADD_SIGNER
FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY
FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START
FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND
FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS
FKO_ERROR_GPGME_DECRYPT_FAILED
FKO_ERROR_GPGME_BAD_HOME_DIR
FKO_ERROR_GPGME_SET_HOME_DIR
);
# The FKO constants. These are manually pulled from fko.h (for now).
#
use constant {
# Message types
FKO_COMMAND_MSG => 0,
FKO_ACCESS_MSG => 1,
FKO_NAT_ACCESS_MSG => 2,
FKO_CLIENT_TIMEOUT_ACCESS_MSG => 3,
FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG => 4,
FKO_LOCAL_NAT_ACCESS_MSG => 5,
FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG => 6,
# Digest types
FKO_DIGEST_MD5 => 1,
FKO_DIGEST_SHA1 => 2,
FKO_DIGEST_SHA256 => 3,
# Encryption types
FKO_ENCRYPTION_RIJNDAEL => 1,
FKO_ENCRYPTION_GPG => 2,
# FKO error codes
FKO_SUCCESS => 0,
FKO_ERROR_CTX_NOT_INITIALIZED => 1,
FKO_ERROR_MEMORY_ALLOCATION => 2,
FKO_ERROR_INVALID_DATA => 3,
FKO_ERROR_DATA_TOO_LARGE => 4,
FKO_ERROR_USERNAME_UNKNOWN => 5,
FKO_ERROR_INCOMPLETE_SPA_DATA => 6,
FKO_ERROR_MISSING_ENCODED_DATA => 7,
FKO_ERROR_INVALID_DIGEST_TYPE => 8,
FKO_ERROR_INVALID_ALLOW_IP => 9,
FKO_ERROR_INVALID_SPA_COMMAND_MSG => 10,
FKO_ERROR_INVALID_SPA_ACCESS_MSG => 11,
FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG => 12,
FKO_ERROR_INVALID_ENCRYPTION_TYPE => 13,
FKO_ERROR_WRONG_ENCRYPTION_TYPE => 14,
FKO_ERROR_DECRYPTION_SIZE => 15,
FKO_ERROR_DECRYPTION_FAILURE => 16,
FKO_ERROR_DIGEST_VERIFICATION_FAILED => 17,
FKO_ERROR_UNSUPPORTED_FEATURE => 18,
FKO_ERROR_UNKNOWN => 19,
# Start GPGME-related errors
GPGME_ERR_START => 20,
FKO_ERROR_MISSING_GPG_KEY_DATA => 21,
FKO_ERROR_GPGME_NO_OPENPGP => 22,
FKO_ERROR_GPGME_CONTEXT => 23,
FKO_ERROR_GPGME_PLAINTEXT_DATA_OBJ => 24,
FKO_ERROR_GPGME_SET_PROTOCOL => 25,
FKO_ERROR_GPGME_CIPHER_DATA_OBJ => 26,
FKO_ERROR_GPGME_BAD_PASSPHRASE => 27,
FKO_ERROR_GPGME_ENCRYPT_SIGN => 28,
FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY => 29,
FKO_ERROR_GPGME_SIGNER_KEYLIST_START => 30,
FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND => 31,
FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS => 32,
FKO_ERROR_GPGME_ADD_SIGNER => 33,
FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY => 34,
FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START => 35,
FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND => 36,
FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS => 37,
FKO_ERROR_GPGME_DECRYPT_FAILED => 38,
FKO_ERROR_GPGME_BAD_HOME_DIR => 39,
FKO_ERROR_GPGME_SET_HOME_DIR => 40,
};
1;
###EOF###
+4954
View File
File diff suppressed because it is too large Load Diff
+48
View File
@@ -0,0 +1,48 @@
##############################################################################
#
# File: 00_init.t
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Test suite file for FKO perl module init functionality.
#
##############################################################################
#
use Test::More tests => 6;
# 1 - Use test.
#
BEGIN { use_ok('FKO') };
# Test support vars
#
my $test_spa_data = '/6jQlii54itZX2d7uQb0CzKgBEKk9T9dOD5COpZM6tdL7I95+GXvbjBgCoDObwTpBSWGEPPEpLmiVIe0iQoEMRT4bDWindoHopxggByzr3aOToQZAhBgEIsMfC+ucz6sragIieQORkmr3OjtOAHI1hZjSMXadiXKo';
my $test_spa_data_pw = 'sdf';
##############################################################################
# 2 - Require test
require_ok( FKO );
# 3 - Init empty
#
my $f1 = FKO->new();
isa_ok( $f1, 'FKO' );
# 4 - Destroy empty
#
$f1->destroy();
ok(!defined($f1->{_ctx}));
# 5 - Init with data
#
my $f2 = FKO->new($test_spa_data, $test_spa_data_pw);
isa_ok( $f2, 'FKO' );
# 6 - Destroy full
#
$f2->destroy();
ok(!defined($f2->{_ctx}));
###EOF###
+59
View File
@@ -0,0 +1,59 @@
##############################################################################
#
# File: 01_constants.t
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Test suite file for FKO perl module functions.
#
##############################################################################
#
BEGIN {
use FKO qw(:all);
our $tc_total = scalar(@FKO::MSG_TYPES)
+ scalar(@FKO::DIGEST_TYPES)
+ scalar(@FKO::ENCRYPTION_TYPES)
+ scalar(@FKO::ERROR_CODES);
}
use Test::More tests => $tc_total + 1;
my $tc_cnt = 0;
# 1-7 - Message type constants
#
foreach my $mt (@FKO::MSG_TYPES) {
$tc_cnt++;
my $val = eval $mt;
ok(defined($val), "Message Type Constant: $mt");
}
# 8-10 - Digest type constants
#
foreach my $dt (@FKO::DIGEST_TYPES) {
$tc_cnt++;
my $val = eval $dt;
ok(defined($val), "Digest Type Constant: $dt");
}
# 11-12 - Encryption type constants
#
foreach my $et (@FKO::ENCRYPTION_TYPES) {
$tc_cnt++;
my $val = eval $et;
ok(defined($val), "Encryption Type Constant: $et");
}
# 13-53 - Encryption type constants
#
foreach my $ec (@FKO::ERROR_CODES) {
$tc_cnt++;
my $val = eval $ec;
ok(defined($val), "Encryption Type Constant: $ec");
}
# Did we test all of the constants?
#
is($tc_total, $tc_cnt, "Expected $tc_total constants: found $tc_cnt");
###EOF###
+221
View File
@@ -0,0 +1,221 @@
##############################################################################
#
# File: 01_functions.t
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Test suite file for FKO perl module functions.
#
##############################################################################
#
use FKO;
use Test::More tests => 96;
# Test spa data support vars
#
my (
$tsd, $tsd_pw, $tsd_rand, $tsd_user, $tsd_time, $tsd_ver,
$tsd_msg_type, $tsd_msg, $tsd_nat_access, $tsd_server_auth,
$tsd_client_timeout, $tsd_digest, $tsd_encoded,
$tsd_digest_type, $tsd_encryption_type
);
# Preset for test
#
$tuser = 'bubba';
$tuser_pw = 'tsd-bubba';
# Defaults
#
my $def_tsd_msg = '0.0.0.0,tcp/22';
my $def_encryption_type = FKO::FKO_ENCRYPTION_RIJNDAEL;
my $def_digest_type = FKO::FKO_DIGEST_SHA256;
my $def_msg_type = FKO::FKO_ACCESS_MSG;
my $err;
##############################################################################
# 1 - Create
#
my $f1_now = time();
my $f1 = FKO->new();
ok($f1, 'Create f1');
# 2-9 - Check defaults exist and are correct value.
#
$tsd_rand = $f1->rand_value();
ok($tsd_rand =~ /^\d{16}$/, 'rand_value format');
$tsd_user = $f1->username();
ok($tsd_user =~ /^\w+/, 'username defined');
$tsd_time = $f1->timestamp();
ok($tsd_time =~ /^\d+$/, 'timestamp format');
ok(($tsd_time - $f1_now) < 2, 'default timestamp value');
$tsd_ver = $f1->version();
ok($tsd_ver =~ /^\d+\.\d+\.\d+$/, 'version format');
$tsd_encryption_type = $f1->encryption_type();
ok($tsd_encryption_type == $def_encryption_type, 'default encryption type');
$tsd_digest_type = $f1->digest_type();
ok($tsd_digest_type == $def_digest_type, 'default digest type');
$tsd_msg_type = $f1->spa_message_type();
ok($tsd_msg_type == $def_msg_type, 'default message type');
# 10-11 - set and verify username
#
$err = $f1->username($tuser);
ok($err == 0, 'set username');
ok($f1->username() eq $tuser, 'set username value');
# 12-13 - set and verify spa message string
#
$err = $f1->spa_message($def_tsd_msg);
ok($err == 0, 'set spa message');
ok($f1->spa_message() eq $def_tsd_msg, 'set spa message value');
# 14 - Finalize the spa data (encode fields , compute digest, encrypt,
# and encode all)
#
$err = $f1->spa_data_final($tuser_pw);
ok($err == 0, 'f1 spa data final');
# 15-16 - Get some of the current spa data for later tests.
#
$tsd = $f1->spa_data();
ok($tsd, 'f1 get spa data');
$tsd_digest = $f1->spa_digest();
ok($tsd_digest, 'f1 get spa digest');
# 17 - create a new object based on the spa data produced by f1.
#
my $f2 = FKO->new($tsd, $tuser_pw);
ok( $f2 );
# 18-31 - Ensure the f2 fields match the f1 fields
#
compare_fko($f1, $f2, 'f1-f2');
# 32-37 - Change digest_type and timestamp in f1 and recompute, then
# make a new fko object based on f1's spa_data.
#
$err = $f1->digest_type(FKO::FKO_DIGEST_SHA1);
ok($err == 0, 'f1 set digest to sha1');
is($f1->digest_type(), FKO::FKO_DIGEST_SHA1, 'verify set digest sha1');
ok($f1->timestamp(5) == 0, 'reset timestamp 1');
isnt($f1->timestamp(), $f2->timestamp(), 'verify new timestamp 1');
ok($f1->spa_data_final('testme') == 0, 'f1 recompute spa data 1');
my $f3 = FKO->new($f1->spa_data(), 'testme');
ok($f3, 'create fko object f3');
# 38-51 - Compare f1 and f3
#
compare_fko($f1, $f3, 'f1-f3');
# 52-57 - Change digest_type and timestamp in f1 and recompute, then
# make a new fko object based on f1's spa_data.
#
$err = $f2->digest_type(FKO::FKO_DIGEST_MD5);
ok($err == 0, 'f1 set digest to md5');
is($f2->digest_type(), FKO::FKO_DIGEST_MD5, 'verify set digest sha1');
my $tts = $f2->timestamp();
ok($f2->timestamp(10) == 0, 'reset timestamp 2');
isnt($f2->timestamp(), $tts, 'verify new timestamp 2');
ok($f2->spa_data_final('metest') == 0, 'f2 recompute spa data 1');
my $f4 = FKO->new($f2->spa_data(), 'metest');
ok($f4, 'create fko object f4');
# 58-71 - Compare f1 and f4
#
compare_fko($f1, $f3, 'f2-f4');
# Clean up what we have so far
#
$f1->destroy();
$f2->destroy();
$f3->destroy();
$f4->destroy();
### General function tests.
# 72 - A fresh object to work with.
#
$f1 = FKO->new();
ok($f1, 'Create f1 #2');
# 73-74 - Force rand value.
#
ok($f1->rand_value('0123456789012345') == 0, 'force rand value');
is($f1->rand_value(), '0123456789012345', 'verify force rand_value');
# 75-88 - Iterate over setting message type
#
my @msg_types = (
FKO::FKO_COMMAND_MSG,
FKO::FKO_ACCESS_MSG,
FKO::FKO_NAT_ACCESS_MSG,
FKO::FKO_CLIENT_TIMEOUT_ACCESS_MSG,
FKO::FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG,
FKO::FKO_LOCAL_NAT_ACCESS_MSG,
FKO::FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG
);
foreach my $mt ( @msg_types ) {
ok($f1->spa_message_type($mt) == 0, "set msg_type to $mt");
is($f1->spa_message_type(), $mt, "verify msg_type is $mt");
}
# 89-90 - SPA message
#
ok($f1->spa_message('1.1.1.1,udp/111') == 0, 'set spa message');
is($f1->spa_message(), '1.1.1.1,udp/111', 'verify spa message');
# 91-92 - Nat Access
#
ok($f1->spa_nat_access('1.2.1.1,udp/211') == 0, 'set nat_access message');
is($f1->spa_nat_access(), '1.2.1.1,udp/211', 'verify nat_access message');
# 93-94 - Server Auth
#
ok($f1->spa_server_auth('crypt,bubba') == 0, 'set server_auth message');
is($f1->spa_server_auth(), 'crypt,bubba', 'verify server_auth message');
# 95-96 - Client Timeout
#
ok($f1->spa_client_timeout(666) == 0, 'set client_timeout');
is($f1->spa_client_timeout(), 666, 'verify client_timeout');
##############################################################################
# Compare fko object fields for equality
# Runs 14 tests.
#
sub compare_fko {
my ($fko1, $fko2, $tn) = @_;
is($fko1->encryption_type(), $fko2->encryption_type(), "$tn encryption_type compare");
is($fko1->digest_type(), $fko2->digest_type(), "$tn digest_type compare");
is($fko1->rand_value(), $fko2->rand_value(), "$tn rand value compare");
is($fko1->username(), $fko2->username(), "$tn username compare");
is($fko1->timestamp(), $fko2->timestamp(), "$tn timestamp compare");
is($fko1->version(), $fko2->version(), "$tn version compare");
is($fko1->spa_message_type(), $fko2->spa_message_type(), "$tn spa_message_type compare");
is($fko1->spa_message(), $fko2->spa_message(), "$tn spa_message compare");
is($fko1->spa_nat_access(), $fko2->spa_nat_access(), "$tn spa_nat_access compare");
is($fko1->spa_server_auth(), $fko2->spa_server_auth(), "$tn spa_server_auth compare");
is($fko1->spa_client_timeout(), $fko2->spa_client_timeout(), "$tn spa_client_timeout compare");
is($fko1->spa_digest(), $fko2->spa_digest(), "$tn spa_digest compare");
is($fko1->encoded_data(), $fko2->encoded_data(), "$tn encoded_data compare");
is($fko1->spa_data(), $fko2->spa_data(), "$tn spa_data compare");
}
sub create
###EOF###
+90
View File
@@ -0,0 +1,90 @@
##############################################################################
#
# File: 01_functions.t
#
# Author: Damien S. Stuart <dstuart@dstuart.org>
#
# Purpose: Test suite file for FKO perl module functions.
#
##############################################################################
#
use FKO qw(:all);
use Test::More tests => 11;
# Test spa data support vars
#
my (
$tsd, $tsd_pw, $tsd_rand, $tsd_user, $tsd_time, $tsd_ver,
$tsd_msg_type, $tsd_msg, $tsd_nat_access, $tsd_server_auth,
$tsd_client_timeout, $tsd_digest, $tsd_encoded,
$tsd_digest_type, $tsd_encryption_type
);
# Preset for test
#
#$tuser = 'bubba';
#$tuser_pw = 'tsd-bubba';
my $err;
##############################################################################
my $f1_now = time();
my $f1 = FKO->new();
# 1 -Try for invalid encryption type
#
$err = $f1->encryption_type(-1);
ok($err == FKO_ERROR_INVALID_DATA, 'invalid encryption type error test');
# 2 -Try for invalid digest type
#
$err = $f1->digest_type(-1);
ok($err == FKO_ERROR_INVALID_DATA, 'invalid digest type error test');
# 3 -Try for invalid spa message type
#
$err = $f1->spa_message_type(-1);
ok($err == FKO_ERROR_INVALID_DATA, 'invalid message type error test');
# 4-5 - Bad rand value size
#
$err = $f1->rand_value('666');
ok($err == FKO_ERROR_INVALID_DATA, 'rand val small error test');
$err = $f1->rand_value('66666666666666666');
ok($err == FKO_ERROR_INVALID_DATA, 'rand val big error test');
# 6 - Final with bad data
#
$err = $f1->spa_data_final("xxx");
ok($err == FKO_ERROR_INCOMPLETE_SPA_DATA, 'invalid spa_data_final error test');
# 7 - Good spa data final for further tests.
#
$f1->spa_message("0.0.0.0,tcp/22");
$err = $f1->spa_data_final("xxx");
ok($err == FKO_SUCCESS, 'spa_data_final');
# 8-10 - New object from f1 data with good pw, bad pw, then no pw
#
my $f2 = FKO->new($f1->spa_data(), 'xxx');
ok($f2, 'create fko object f2 (good pw)');
$f2->destroy();
$f2 = FKO->new($f1->spa_data(), 'bad_pw');
is($f2, undef, 'create fko object f2 (bad pw)');
$f2->destroy() if($f2); #Just in case
$f2 = FKO->new($f1->spa_data());
ok($f2, 'create fko object f2 (no pw)');
# 11 - Bad decrypt pw
#
$err = $f2->decrypt_spa_data('badpw');
ok($err == FKO_ERROR_DECRYPTION_FAILURE, 'decrypt with bad pw');
# TODO: add gpg test and errors.
###EOF###
+3
View File
@@ -0,0 +1,3 @@
const char * T_PTROBJ
fko_ctx_t T_PTROBJ
fko_ctx_t * T_PTROBJ