1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
# Copyright (c) 2002 Graham Barr <gbarr@pobox.com>. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
package Authen::SASL::Perl;
use strict;
use vars qw($VERSION);
use Carp;
$VERSION = "1.04";
my %secflags = (
noplaintext => 1,
noanonymous => 1,
nodictionary => 1,
);
my %have;
sub client_new {
my ($pkg, $parent, $service, $host, $secflags) = @_;
my @sec = grep { $secflags{$_} } split /\W+/, lc($secflags || '');
my $self = {
callback => { %{$parent->callback} },
service => $service || '',
host => $host || '',
};
my @mpkg = sort {
$b->_order <=> $a->_order
} grep {
my $have = $have{$_} ||= (eval "require $_;" and $_->can('_secflags')) ? 1 : -1;
$have > 0 and $_->_secflags(@sec) == @sec
} map {
(my $mpkg = __PACKAGE__ . "::$_") =~ s/-/_/g;
$mpkg;
} split /[^-\w]+/, $parent->mechanism
or croak "No SASL mechanism found\n";
$mpkg[0]->_init($self);
}
sub _order { 0 }
sub code { defined(shift->{error}) || 0 }
sub error { shift->{error} }
sub service { shift->{service} }
sub host { shift->{host} }
sub set_error {
my $self = shift;
$self->{error} = shift;
return;
}
# set/get property
sub property {
my $self = shift;
my $prop = $self->{property} ||= {};
return $prop->{ $_[0] } if @_ == 1;
my %new = @_;
@{$prop}{keys %new} = values %new;
1;
}
sub callback {
my $self = shift;
return $self->{callback}{$_[0]} if @_ == 1;
my %new = @_;
@{$self->{callback}}{keys %new} = values %new;
$self->{callback};
}
# Should be defined in the mechanism sub-class
sub mechanism { undef }
sub client_step { undef }
sub client_start { undef }
# Private methods used by Authen::SASL::Perl that
# may be overridden in mechanism sub-calsses
sub _init {
my ($pkg, $href) = @_;
bless $href, $pkg;
}
sub _call {
my ($self, $name) = @_;
my $cb = $self->{callback}{$name};
if (ref($cb) eq 'ARRAY') {
my @args = @$cb;
$cb = shift @args;
return $cb->($self, @args);
}
elsif (ref($cb) eq 'CODE') {
return $cb->($self);
}
return $cb;
}
sub _secflags { 0 }
sub securesocket { $_[1] }
1;
|