Authen-Krb5-Simple-0.43/0000755000175000017500000000000011702322353014650 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/Changes0000644000175000017500000000231311236166263016152 0ustar dstuartdstuartRevision history for Perl extension Authen::Krb5::Simple. 0.42 Mon Aug 03 23:41 2009 - Changed handling of null/empty passwords. - Added internal (non-krb) error message handling. - Added null/empty password tests. - Updated tests to use Test::More. - Minor code refactoring. - Updated docs. 0.40 Sun Feb 24 18:35:42 2008 - Added the Devel::CheckLib. - Changes to Makefile.PL and the way it tries to determine whether or not the Kerberos libs are available using Devel::CheckLib. - Documentation and test tweaks. 0.32 Mon Feb 21 23:50:37 2005 - Documentation updates for clarification. 0.31 Fri Mar 14 07:14:33 2003 - Fixed bug where realm was not properly set by the constructor (Thanks to Jorgen Andreasen for pointing that out to me). 0.30 Sun Jan 19 15:56:00 2003 - Removed export of authenticate method. - Added the CONFIG file for user auth tests, which are now optional. - Minor code tweaks. 0.20 Wed Dec 25 20:53:23 2002 - Remove attempted support for empty passwords (currently causes a core dump when perl exits). 0.10 Wed Dec 25 12:04:23 2002 - original version; created by h2xs 1.21 with options -A -n AuthKrb5 -v 0.10 -x Authen-Krb5-Simple-0.43/Makefile.PL0000644000175000017500000000347011702322046016625 0ustar dstuartdstuart############################################################################### # # File: Makefile.PL # # Author: Damien S. Stuart # # Purpose: Makefile.PL for the Authen::Krb5::Simple module. # ############################################################################### # use lib 'inc'; use Devel::CheckLib; use ExtUtils::MakeMaker; my ($krb5_inc, $krb5_lib); # Places we might find Kerberos5 libs. # my @krb_lib_dirs = qw( /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /usr/lib64/krb5 /usr/lib/krb5 /usr/local/lib64/krb5 /usr/local/lib/krb5 /usr/lib64/krb /usr/lib/krb /usr/local/lib64/krb /usr/local/lib/krb /opt/krb5/lib64 /opt/krb5/lib /opt/krb/lib64 /opt/krb/lib /usr/heimdal/lib64 /usr/heimdal/lib /usr/local/heimdal/lib64 /usr/local/heimdal/lib /opt/heimdal/lib64 /opt/heimdal/lib ); # If the ENV vars are specified, use them. # if(exists($ENV{KRB5_INCLUDE})) { $krb5_inc = "-I$ENV{KRB5_INCLUDE}"; } if(exists($ENV{KRB5_LIB})) { $krb5_lib = "-L$ENV{KRB5_LIB}"; unshift(@krb_lib_dirs, $ENV{KRB5_LIB}); } # See if the needed libs are available. Take a shot at several "possible" # locations for these libs. # check_lib_or_exit( lib => [qw( krb5 )], libpath => \@krb_lib_dirs ) unless($ENV{skip_lib_check}); # Write out the Makefile # WriteMakefile( 'NAME' => 'Authen::Krb5::Simple', 'VERSION_FROM' => 'lib/Authen/Krb5/Simple.pm', 'PREREQ_PM' => { 'Test::More', }, ($] >= 5.006 ? ( ABSTRACT => 'Perl module that performs Kerberos 5 authentication', AUTHOR => 'Damien S. Stuart ') : () ), 'LIBS' => ["$krb5_lib -lkrb5"], 'DEFINE' => '', 'INC' => $krb5_inc, ); ###EOF### Authen-Krb5-Simple-0.43/CONFIG0000644000175000017500000000144211236171022015536 0ustar dstuartdstuart############################################################################### # # File: CONFIG # # Purpose: Specify test configuration parameters (user and password) for # the Authen::Krb5::Simple module. # ############################################################################### # # Uncomment and specify the test realm, username, and password if you want # to run a more complete authentication test. Leave them commented out to # skip the user authentication test. # # Note: TEST_REALM is optional. If omitted, the default realm for the # local system will be used. # # ** If you use these make sure the realm and user exist and the password # is correct. Otherwise, the test will fail. # #TEST_REALM TESTREALM.COM #TEST_USER testuser #TEST_PASS testpass ###EOF### Authen-Krb5-Simple-0.43/t/0000755000175000017500000000000011702322353015113 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/t/01-compile.t0000644000175000017500000000104511235727250017154 0ustar dstuartdstuart############################################################################### # Authen::Krb5::Simple Test Script # # File: 01-compile.t # # Purpose: Make sure the modules compiles and loads with no error # ############################################################################### # use Test::More tests => 3; # 1 - Use test. # BEGIN { use_ok('Authen::Krb5::Simple') } # 2 - Require test. # require_ok( Authen::Krb5::Simple ); # 3 - Is what we is. # my $krb = Authen::Krb5::Simple->new(); isa_ok( $krb, 'Authen::Krb5::Simple'); ###EOF### Authen-Krb5-Simple-0.43/t/02-ops.t0000644000175000017500000000630011236166040016320 0ustar dstuartdstuart############################################################################### # Authen::Krb5::Simple Test Script # # File: 02-ops.t # # Purpose: Make sure we can create and use an Authen::Krb5::Simple object. # ############################################################################### # use strict; use Test::More tests => 16; use Authen::Krb5::Simple; # Get test user params (if any) # my $tdata = get_test_data(); my $krb = Authen::Krb5::Simple->new(); # (1) Valid object. # isa_ok($krb, 'Authen::Krb5::Simple', 'Valid object check'); my $errcode; my $errstr; my $ret; # (2-7) Good pw # my $no_user_data = (!defined($tdata->{user}) and !defined($tdata->{password})); SKIP: { skip "No user/password data provided", 6 if($no_user_data); my $tuser = $tdata->{user}; my $tpass = $tdata->{password}; $tuser .= "\@$tdata->{realm}" if(defined($tdata->{realm})); $ret = $krb->authenticate($tuser, $tpass) unless($no_user_data); $errcode = $krb->errcode(); $errstr = $krb->errstr(); ok($ret, 'Good username and password authentication'); # Valid error conditions # ok($errcode == 0, "Error code 0 check: Got '$errcode'"); ok($errstr eq '', "Error string empty check: Got '$errstr'"); # Now munge the pw and make sure we get the expected responses # $ret = $krb->authenticate($tuser, "x$tpass") unless($no_user_data); $errcode = $krb->errcode(); $errstr = $krb->errstr(); ok(!$ret, "Return value 'true' check: Got '$ret'"); ok($errcode != 0, "Non-zero error code check: Got '$errcode'"); ok($errstr ne '', "Non-empty error string check: Got '$errstr'"); } # (8-13) Null and Empty password # $ret = $krb->authenticate('_not_a_user_'); ok($ret==0, "Null password returns 0 check: Got '$ret'"); $errcode = $krb->errcode(); $errstr = $krb->errstr(); ok($errcode eq 'e1', "Null password error code of 'e1' check: Got '$errcode'"); ok($errstr =~ /Null or empty password not supported/, "Null password error string check: Got '$errstr'"); $ret = $krb->authenticate('_not_a_user_', ''); ok($ret==0, "Empty password should return 0: Got '$ret'"); $errcode = $krb->errcode(); $errstr = $krb->errstr(); ok($errcode eq 'e1', "Empty password error code of 'e1' check: Got '$errcode'"); ok($errstr =~ /Null or empty password not supported/, "Null password error string check: Got '$errstr'"); # (14) Bad user and pw # $ret = $krb->authenticate('_xxx', '_xxx'); ok($ret == 0, "Bad user and PW Check returns '0': Got '$ret'"); $errcode = $krb->errcode(); $errstr = $krb->errstr(); # (15-16) Valid error conditions # ok($errcode != 0, "Bad user and PW check non-zero error code: Got '$errcode'"); ok($errstr, "Bad user and PW error string check"); ### End of Tests ### sub get_test_data { my %tdata; unless(open(CONF, "< CONFIG")) { diag("** Unable to read CONFIG file: $!"); diag("** Skipping user auth tests"); return undef; } while() { chomp; next if(/^\s*#|^\s*$/); $tdata{user} = $1 if(/^\s*TEST_USER\s+(.*)/); $tdata{password} = $1 if(/^\s*TEST_PASS\s+(.*)/); $tdata{realm} = $1 if(/^\s*TEST_REALM\s+(.*)/); } close(CONF); return(\%tdata); } ###EOF### Authen-Krb5-Simple-0.43/README0000644000175000017500000000442311236442141015533 0ustar dstuartdstuartAuthen::Krb5::Simple version 0.42 =============================================================================== The Authen::Krb5::Simple module provides a means to authenticate a user/password using Kerberose 5. Simply use this module and call its authenticate function with a username (or user@KRB_REALM) and a password. Detailed usage information can be found in the module's perldoc. INSTALLATION To install this module edit the CONFIG file to set test kerberos realm, username and password. These are optional. If either the username or password is not given, then the user auth tests will be skipped. If a realm is specified, it will be used for the test. Otherwise, the default realm for the system will be used (if properly configured of course). You can also specify a location of the Kerberos include and libs directories in the environment variables KRB5_INCLUDE and KRB5_LIB respectively. Setting these will cause the build to try them first. This would normally be used if your Kerberos libraries are in a non-standard location, or you wanted to overide the system defaults. Once that is done, then type the following: perl Makefile.PL make make test make install Note: In the absence of the KRB5_INCLUDE and KRB4LIB environment variables mentioned above, the module will make an attempt to try and find out the location of the Kerberos 5 include and lib files. If you continue to get "Can't build and link to 'xxx'" errors from the "perl Makefile.PL" command. you can try setting the skip_lib_check environment variable to skip the lib check (this was necessary on some FreeBSD systems that had conflicting libkrb5.so files). For example: skip_lib_check=1 perl Makefile.PL If that doesn't work, you will need to manually override by setting the environment variables (if not already set) or editing Makfile.PL to directly. DEPENDENCIES This module requires the Kerberos 5 header and library files installed on the local system. ------------------------------------------------------------------------------- COPYRIGHT AND LICENCE Copyright (c) 2003-2009 Damien S. Stuart. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Authen-Krb5-Simple-0.43/lib/0000755000175000017500000000000011702322353015416 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/lib/Authen/0000755000175000017500000000000011702322353016642 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/lib/Authen/Krb5/0000755000175000017500000000000011702322353017445 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/lib/Authen/Krb5/Simple.pm0000644000175000017500000001314011702322147021234 0ustar dstuartdstuart############################################################################### # # File: Simple.pm # # Author: Damien S. Stuart # # Purpose: Perl module for basic authenication using Kerberose 5. # # ############################################################################### # package Authen::Krb5::Simple; use 5.006; use strict; use warnings; use Carp; require DynaLoader; our @ISA = qw(DynaLoader); our $VERSION = '0.43'; bootstrap Authen::Krb5::Simple $VERSION; # Create the Kerberos 5 object. # sub new { my $class = shift; my (%args) = @_; bless { _err_code => 0, _realm => $args{realm} || '' }, $class } # Perform the authentication # sub authenticate { my $self = shift; my $user = shift || croak "Missing arg: username\n"; my $pw = shift; if(!defined($pw) or $pw eq '') { # Codes staring with 'e' are internal to this module. # $self->{_err_code} = 'e1'; return 0; } # If a realm is specified, prepend it to the username (as long as the # username does not already have a realm component). # if($self->{_realm} and $user !~ /@\S+$/) { $user .= "\@$self->{_realm}"; } $self->{_err_code} = krb5_auth($user, $pw); return(($self->{_err_code} == 0) ? 1 : 0); } # Return the error string from the most recent authenticate function. # sub errstr { # Check for module internal (non-krb) error. If it is return the # appropriate error string (there is only one at present). # if($_[0]->{_err_code} =~ /^e(\d+)/) { return('Null or empty password not supported') if($1 == 1); } # Otherwise, let krb5_errstr tell us... # return ($_[0]->{_err_code} == 0) ? '' : krb5_errstr($_[0]->{_err_code}); } # Return the error code from the most recent authenticate function. # sub errcode { return $_[0]->{_err_code}; } # Get or set the default realm # sub realm { my $self = shift; my $arg = shift; $self->{_realm} = $arg if(defined($arg)); return $self->{_realm}; } 1; __END__ =head1 NAME Authen::Krb5::Simple - Basic user authentication using Kerberos 5 =head1 SYNOPSIS use Authen::Krb5::Simple; # Create a new Authen::Krb5::Simple object using # the system default realm. # my $krb = Authen::Krb5::Simple->new(); # Authenticate a user. # my $authen = $krb->authenticate($user, $password); unless($authen) { my $errmsg = $krb->errstr(); die "User: $user authentication failed: $errmsg\n"; } # Get the current default realm. # my $realm = $krb->realm(); # Set the current realm # $krb->realm('MY.NEW.REALM'); # Create a new object pointing to another realm. # my $alt_krb = Authen::Krb5::Simple->new(realm => 'OTHER.REALM'); ... =head1 DESCRIPTION The C module provides a means to authenticate a user/password using Kerberos 5 protocol. The module's authenticate function takes a username (or user@kerberos_realm) and a password, and authenticates that user using the local Kerberos 5 installation. It was initially created to allow perl scripts to perform authentication against a Microsoft Active Directory (AD) server configured to accept Kerberos client requests. B This module only performs simple authentication. It does not get, grant, use, or retain any kerberos tickets. It will check user credentials against the Kerberos server (as configured on the local system) each time the I method is called. =head1 CONSTRUCTOR B =over The I method creates the I object. It can take an optional argument hash. At present the only recognized argument is C. If no realm is specified, the default realm for the local host will be assumed. Once set, the specified realm will be used for all subsequent authentication calls. The realm can be changed using the I function (see below). B Using the default realm: my $krb = Authen::Krb5::Simple->new(); specifying a realm: my $krb = Authen::Krb5::Simple->new(realm => 'another.realm.net'); =back =head1 METHODS B =over the I method takes the user (or user@realm) and a password, and uses kerberos 5 (the local systems installation) to authenticate the user. if the user/password is good, I will return a true value. Otherwise, a false value is returned and the error code is stored in the object. if($krb->authenticate($user, $pw)) { print "$user authentication successful\n"; } else { print "$user authentication failed: ", $krb->errstr(), "\n"; } =back B B =over The I method is used to set or get the current default realm. If an argument is passed to this method, the default realm is set to that value. If no argument is supplied, the current realm is returned. =back B =over The I method will return the error message from the most recent I call. =back B =over The I method will return the krb5 error code from the most recent I call. This value will not be very useful. Use the I method to get a meaningful error message. =back =head1 BUGS This version of I does not support null or empty passwords. If you pass an undefined value or empty string (C<''>) as a password, I return false and set the error to indicate that null or empty passwords are not supported. =head1 AUTHOR Damien S. Stuart, Edstuart@dstuart.orgE =head1 SEE ALSO L, Kerberos5 documentation. =cut ###EOF### Authen-Krb5-Simple-0.43/META.yml0000664000175000017500000000073111702322353016124 0ustar dstuartdstuart--- #YAML:1.0 name: Authen-Krb5-Simple version: 0.43 abstract: Perl module that performs Kerberos 5 authentication license: ~ author: - Damien S. Stuart generated_by: ExtUtils::MakeMaker version 6.42 distribution_type: module requires: Test::More: meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.3.html version: 1.3 Authen-Krb5-Simple-0.43/Simple.xs0000644000175000017500000000306511235727230016465 0ustar dstuartdstuart/* ****************************************************************************** * * File: Simple.xs * * Author: Damien S. Stuart * * Purpose: .xs file for the Authen::Krb5::Simple Perl module. * * ****************************************************************************** */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include int _krb5_auth(char* user, char* pass) { int krbret; krb5_context ctx; krb5_creds creds; krb5_principal princ; int ret = 0; /* Initialize krb5 context... */ if ((krbret = krb5_init_context(&ctx))) { return krbret; } memset(&creds, 0, sizeof(krb5_creds)); /* Get principal name... */ if ((krbret = krb5_parse_name(ctx, user, &princ))) { ret = krbret; goto free_context; } /* Check the user's pasword... */ if ((krbret = krb5_get_init_creds_password( ctx, &creds, princ, pass, 0, NULL, 0, NULL, NULL))) { ret = krbret; } krb5_free_cred_contents(ctx, &creds); krb5_free_principal(ctx, princ); free_context: krb5_free_context(ctx); return(ret); } MODULE = Authen::Krb5::Simple PACKAGE = Authen::Krb5::Simple PROTOTYPES: DISABLE int krb5_auth(user, password) INPUT: char * user; char * password; CODE: RETVAL = _krb5_auth(user, password); OUTPUT: RETVAL char* krb5_errstr(errcode) INPUT: int errcode; INIT: char* result = (char*)error_message(errcode); CODE: RETVAL = result; OUTPUT: RETVAL Authen-Krb5-Simple-0.43/MANIFEST0000644000175000017500000000033411702322354016002 0ustar dstuartdstuartCONFIG Changes Makefile.PL MANIFEST MANIFEST.SKIP README Simple.xs inc/Devel/CheckLib.pm lib/Authen/Krb5/Simple.pm t/01-compile.t t/02-ops.t META.yml Module meta-data (added by MakeMaker) Authen-Krb5-Simple-0.43/MANIFEST.SKIP0000644000175000017500000000004010760342056016545 0ustar dstuartdstuart\bCVS\b .cvsignore .svn Authen- Authen-Krb5-Simple-0.43/inc/0000755000175000017500000000000011702322353015421 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/inc/Devel/0000755000175000017500000000000011702322353016460 5ustar dstuartdstuartAuthen-Krb5-Simple-0.43/inc/Devel/CheckLib.pm0000644000175000017500000002017210760322166020471 0ustar dstuartdstuart# $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. =head2 assert_lib Takes several named parameters. The value of C 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) Likewise, C must if provided either be a string or an array of strings representing additional paths to search for libraries. C must be a C-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: dying in a Makefile.PL or Build.PL may provoke a 'FAIL' report from CPAN Testers' automated smoke testers. Use C instead. =head2 check_lib_or_exit This behaves exactly the same as C 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 or by email. When submitting a bug report, please include the output from running: perl -V perl -MDevel::CheckLib =head1 SEE ALSO L =head1 AUTHORS David Cantrell Edavid@cantrell.org.ukE David Golden Edagolden@cpan.orgE 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;