Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GSSAPI programming help

53 views
Skip to first unread message

Dennis Putnam

unread,
May 18, 2006, 7:27:53 AM5/18/06
to perl...@perl.org
I was told some of you folks are working with Kerberos auth using
GSSAPI. I am trying to do the same thing with POP rather then LDAP
and I am hoping someone here might be able to help me. It is not
obvious to me what I really need to pass in the 'auth' method so I
suspect that is the crux of my problem. When I try to authenticate to
the POP server it fails and all that shows up in the POP log is
'badlogin'. Here is my relevant code:

use strict;
use Net::POP3;
use Authen::SASL;

.
.
.

my $sasl=new Authen::SASL(mechanism=> "GSSAPI SASL",
callback => {
user => $USERNAME,
pass => $PASSWORD,
}
);

my $pop=Net::POP3->new($SERVER)
or die "Unable to connect to mail server: ",$!,"\n";
if ($pop->auth($sasl) > 0) {
my $messages=$pop->list()
or die "Unable to get messages: ",$!,"\n";
}
else {
print "Authentication failed: ",$!,"\n";
}

Note that '$!' contains nothing when it prints my authentication
failed message.

Can someone on this list help me or at least point me to a more
appropriate forum? Thanks.

Quanah Gibson-Mount

unread,
May 18, 2006, 12:14:51 PM5/18/06
to Dennis Putnam, perl...@perl.org

--On Thursday, May 18, 2006 7:27 AM -0400 Dennis Putnam
<dennis...@aimaudit.com> wrote:

> I was told some of you folks are working with Kerberos auth using
> GSSAPI. I am trying to do the same thing with POP rather then LDAP and I
> am hoping someone here might be able to help me. It is not obvious to me
> what I really need to pass in the 'auth' method so I suspect that is the
> crux of my problem. When I try to authenticate to the POP server it
> fails and all that shows up in the POP log is 'badlogin'. Here is my
> relevant code:
>
> use strict;
> use Net::POP3;
> use Authen::SASL;

I was able to use Authen::SASL to do GSSAPI authentication via finger &
whois, using the Authen-SASL-GSSAPI-server package.

The following are my code snippets that may help you in the right direction:

############################################################################
# SASL related subroutines
############################################################################

sub sendreply
{
$SIG{PIPE} = 'IGNORE'; # Client is closing too fast
my ($s,$so) = @_;
$s = " " unless $s;
#print "Sendreply: ",substr($s,0,10),"\n";
syswrite ($so,$s);
}

sub getreply
{
my ($so) = @_;
my $s;
#print "Getreply is waiting.\n";
sysread($so,$s,4096);
#print "Getreply: ",substr($s,0,10),"\n";
return $s;
}


sub query_server {
my ($server, $query, $port) = @_;

# I tried using IO::Socket here, but the load time was noticeable.
# Using Getopt::Long is bad enough. On top of that, IO::Socket doesn't
# return meaningful error codes that I can see, so one can't distinguish
# between, say, "connection refused" and "host unreachable."
my $address = inet_aton ($server)
or die "Can't resolve server name $server\n";
my $proto = getprotobyname 'tcp';
$port ||= 43;
if ($port =~ /\D/) {
my $service = $port;
$port = getservbyname ($service, 'tcp')
or die "Unknown service $service\n";
}

socket (S, PF_INET, SOCK_STREAM, $proto)
or die "Can't create local socket: $!\n";
connect (S, sockaddr_in ($port, $address))
or die "Can't connect to $server: $!\n";
my $oldfh = select S; $| = 1; select $oldfh;

my $remote_ip = inet_ntoa($address);
my ($local_port, $local_ip) = sockaddr_in(getsockname(S));
$local_ip = inet_ntoa($local_ip);
#print "$local_ip;$local_port $remote_ip;$port\n";

my $saslClient = Authen::SASL->new (
mechanism => "GSSAPI",
callback => {
}
);
my $conn = $saslClient->client_new("host", "$remote_ip",
"$local_ip;$local_port", "$remote_ip;$port");

sendreply($conn->client_start(),\*S,0);
while ($conn->need_step) {
sendreply($conn->client_step(&getreply(\*S) ), \*S );
}

--Quanah


--
Quanah Gibson-Mount
Principal Software Developer
ITS/Shared Application Services
Stanford University
GnuPG Public Key: http://www.stanford.edu/~quanah/pgp.html

Dennis Putnam

unread,
May 18, 2006, 12:22:29 PM5/18/06
to Quanah Gibson-Mount, perl...@perl.org
Ouch! Thanks for the reply. I am a perl novice so it will take a
while for me to understand it all. However, this is a lot more
complex then I was lead to believe. I thought most of what you are
doing was done behind the scenes automagically when I created the
SASL object.


Dennis Putnam
Sr. IT Systems Administrator
AIM Systems, Inc.
11675 Rainwater Dr., Suite 200
Alpharetta, GA 30004
Phone: 678-240-4112
Main Phone: 678-297-0700
FAX: 678-297-2666 or 770-576-1000
The information contained in this e-mail and any attachments is
strictly confidential. If you are not the intended recipient, any
use, dissemination, distribution, or duplication of any part of this
e-mail or any attachment is prohibited. If you are not the intended
recipient, please notify the sender by return e-mail and delete all
copies, including the attachments.


Graham Barr

unread,
May 18, 2006, 1:58:07 PM5/18/06
to Quanah Gibson-Mount, Dennis Putnam, perl...@perl.org
On Thu, May 18, 2006 11:14 am, Quanah Gibson-Mount wrote:

>
> I was able to use Authen::SASL to do GSSAPI authentication via finger &
> whois, using the Authen-SASL-GSSAPI-server package.

What you show below is basically what most modules, eg Net::POP3 and
Net::LDAP, do behind the scenes.

I think the question that Dennis needs answered is what to use as callback
values when authenticating using Kerberos, SASL and GSSAPI

Graham.

Achim Grolms

unread,
May 18, 2006, 2:51:59 PM5/18/06
to Dennis Putnam, Graham Barr, perl...@perl.org
On Thursday 18 May 2006 13:27, Dennis Putnam wrote:
> I was told some of you folks are working with Kerberos auth using
> GSSAPI. I am trying to do the same thing with POP rather then LDAP

Using Authen::SASL as a programmer means

1. create a Authen::SASL object

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );

2. Pass this SASL object to the constructor/authentication method
of Protocol object you want to use.

From my point of view the POD of Net::POP3 (2.28) has
no method to pass an Authen::SASL object to Net::POP3
That means that at the Moment the Net::POP3 module can't use
ojects Authen::SASL interface like Authen::SASL::Perl::GSSAPI.

Somthing like

$pop3object->bind( sasl => $sasl );

is missing.

@Graham:
-is that correct?
-can you add that to Net::POP3?

My working example (with Net::LDAP, now part
of the Authen::SASL::Perl::GSSAPI POD) is this:

#! /usr/bin/perl -w

use strict;

use Net::LDAP 0.33;
use Authen::SASL 2.10;

# -------- Adjust to your environment --------
my $adhost = 'theserver.bla.net';
my $ldap_base = 'dc=bla,dc=net';
my $ldap_filter = '(&(sAMAccountName=BLAAGROL))';

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );
my $ldap;
eval {
$ldap = Net::LDAP->new( $adhost,
onerror => 'die',
) or die "Cannot connect to LDAP host '$adhost':
'$@'";
$ldap->bind( sasl => $sasl );
};

if ($@) {
chomp $@;
die "\nBind error : $@",
"\nDetailed SASL error: ", $sasl->error,
"\nTerminated";
}

print "\nLDAP bind() succeeded, working in authenticated state";

my $mesg = $ldap->search( base => $ldap_base,
filter => $ldap_filter );

# -------- evaluate $mesg

Achim Grolms

unread,
May 18, 2006, 3:10:34 PM5/18/06
to Graham Barr, perl...@perl.org, Dennis Putnam
On Thursday 18 May 2006 19:58, Graham Barr wrote:
> On Thu, May 18, 2006 11:14 am, Quanah Gibson-Mount wrote:

> What you show below is basically what most modules, eg Net::POP3 and
> Net::LDAP, do behind the scenes.
>
> I think the question that Dennis needs answered is what to use as callback
> values when authenticating using Kerberos, SASL and GSSAPI

Hmm, I think he needs a way to pass the Authen::SASL object
to the Net::POP3 module.

Net::LDAP simply uses the Authen::SASL interface of the SASL object
passed to bind().

How can that "use the sasl-objetcs interface only" be done with
Net::POP3?

Achim

Achim Grolms

unread,
May 18, 2006, 3:50:31 PM5/18/06
to Graham Barr, Dennis Putnam, perl...@perl.org
On Thursday 18 May 2006 21:10, Achim Grolms wrote:

> How can that "use the sasl-objetcs interface only" be done with
> Net::POP3?

I have no GSSAPI enabeled POP3 Server to test, but my idea is to add
a authsasl() method to Net::POP3 that accepts the Authen::SASL object.
Does that work? I have no chance to test it myself at the moment:

#------usage example--------------
use Authen::SASL 2.10;
use Net::POP3;

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );

$pop = Net::POP3->new('pop3host');
$pop->authsasl($sasl);

my $msgnums = $pop->list; # hashref of msgnum => size
foreach my $msgnum (keys %$msgnums) {
my $msg = $pop->get($msgnum);
print @$msg;
}
$pop->quit;
#------end of usage example--------------

#--------changes to Net::POP3--------------------
# add this to Net::POP3 pm-file
#

sub authsasl {
my ($self, $sasl) = @_;

eval {
require MIME::Base64;
} or $self->set_status(500,["Need MIME::Base64 todo auth"]), return 0;


my $client = $sasl->client_new('pop3',${*$self}{'net_pop3_host'},0);
my $str = $client->client_start;

my @cmd = ("AUTH", $client->mechanism);
my $code;

push @cmd, MIME::Base64::encode_base64($str,'')
if defined $str and length $str;

while (($code = $self->command(@cmd)->response()) == CMD_MORE) {
@cmd = (MIME::Base64::encode_base64(
$client->client_step(
MIME::Base64::decode_base64(
($self->message)[0]
)
), ''
));
}

$code == CMD_OK;
}
#--------end of changes to Net::POP3--------------------

Graham Barr

unread,
May 18, 2006, 3:52:08 PM5/18/06
to ac...@grolmsnet.de, Graham Barr, perl...@perl.org, Dennis Putnam

$pop3->auth($sasl); should work. Maybe the docs need updating.

Graham.


Achim Grolms

unread,
May 18, 2006, 3:58:28 PM5/18/06
to Graham Barr, perl...@perl.org
On Thursday 18 May 2006 21:52, Graham Barr wrote:

> $pop3->auth($sasl); should work. Maybe the docs need updating.

I'm reading the sources of Net::POP3 2.28 (actual CPAN version).
The Code is

#----------------------------------------------------------
sub auth {
my ($self, $username, $password) = @_;

eval {
require MIME::Base64;
require Authen::SASL;
} or $self->set_status(500,["Need MIME::Base64 and Authen::SASL todo
auth"]), return 0;

my $capa = $self->capa;
my $mechanisms = $capa->{SASL} || 'CRAM-MD5';

my $sasl;

if (ref($username) and UNIVERSAL::isa($username,'Authen::SASL')) {
$sasl = $username;
$sasl->mechanism($mechanisms);
}
else {
die "auth(username, password)" if not length $username;
$sasl = Authen::SASL->new(mechanism=> $mechanisms,
callback => { user => $username,
pass => $password,
authname => $username,
});
}
#----------------------------------------------------------

sub auth() does not accept a SASL object as parameter, it creates it's own
SASL object inside.

Achim Grolms

unread,
May 18, 2006, 4:03:43 PM5/18/06
to perl...@perl.org, Graham Barr
On Thursday 18 May 2006 21:58, Achim Grolms wrote:

> if (ref($username) and UNIVERSAL::isa($username,'Authen::SASL')) {
> $sasl = $username;
> $sasl->mechanism($mechanisms);

Yes, and that's the part of the code that accepts the SASL object.
Stupid me.

I am sorry!
Achim

Achim Grolms

unread,
May 18, 2006, 4:07:08 PM5/18/06
to Dennis Putnam, Graham Barr, perl...@perl.org
If the Net::POP3 auth() method accepts

a SASL object this should work:

#------usage example--------------
use Authen::SASL 2.10;
use Net::POP3;

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );
$pop = Net::POP3->new('pop3host');

$pop->auth($sasl);

my $msgnums = $pop->list; # hashref of msgnum => size
foreach my $msgnum (keys %$msgnums) {
my $msg = $pop->get($msgnum);
print @$msg;
}
$pop->quit;
#------end of usage example--------------

Dennis, please try and let us know if this works!

Achim

Don C. Miller

unread,
May 18, 2006, 5:10:37 PM5/18/06
to perl...@perl.org
Achim, or anyone, have you been able to get GSSAPI to work using activestate
perl on a windows system? What requirements are there?

Thanks,
Don

Achim Grolms

unread,
May 18, 2006, 5:24:28 PM5/18/06
to Don C. Miller, perl...@perl.org
On Thursday 18 May 2006 23:10, Don C. Miller wrote:
> Achim, or anyone, have you been able to get GSSAPI to work using
> activestate perl on a windows system? What requirements are there?

The core GSSAPI module is writte in XS.
That means you need the C-compiler the AS Perl
was build with do build the GSSAPI module.
(Like to compile all other modules that should
run with AS-Perl)

An alternative is to

- use cygwin and it's toolchain
- build Perl with cygwin
- Build MIT Kerberos or Heimdal with cygwin
- Build GSSAPI module with cygwin
- Install Authen::SASL::Perl::GSSAPI

Does that help?
Achim

Dennis Putnam

unread,
May 22, 2006, 1:05:55 PM5/22/06
to perl...@perl.org
Did Graham or anyone ever post an answer to this question? I am still
stuck trying to figure out how to get the SASL object to the POP
authentication.

Achim Grolms

unread,
May 22, 2006, 1:22:39 PM5/22/06
to Dennis Putnam, perl...@perl.org
On Monday 22 May 2006 19:05, you wrote:
> Did Graham or anyone ever post an answer to this question?

Yes, Graham and anyone answered on Thursday.
Me wrote on
Thursday 22:07:08

If the Net::POP3 auth() method accepts

a SASL object this should work:

#------usage example--------------
use Authen::SASL 2.10;
use Net::POP3;

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );

Dennis Putnam

unread,
May 22, 2006, 1:50:12 PM5/22/06
to perl...@perl.org
Doesn't work. Nothing is in '$!' but the POP log says "badlogin".

Note that this is OS X Server (10.4.6), if that matters.

Achim Grolms

unread,
May 22, 2006, 2:27:58 PM5/22/06
to Dennis Putnam, perl...@perl.org
On Monday 22 May 2006 19:50, Dennis Putnam wrote:
> Doesn't work. Nothing is in '$!' but the POP log says "badlogin".

Try if this works:

#------usage example--------------
use strict;

use Authen::SASL 2.10 qw(Perl);
use Net::POP3;

my $pop3host = 'pop3host';

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' );

my $pop = Net::POP3->new( $pop3host ) || die "can not connect to $pop3host ";
if ( $pop->auth($sasl) ) {


my $msgnums = $pop->list; # hashref of msgnum => size
foreach my $msgnum (keys %$msgnums) {
my $msg = $pop->get($msgnum);
print @$msg;
}
}

else {
die "\n Authentication error from SASL: \n",
$sasl->error;

Achim Grolms

unread,
May 22, 2006, 4:06:50 PM5/22/06
to Dennis Putnam, perl...@perl.org
On Monday 22 May 2006 20:50, you wrote:
> Thanks. No joy. The error is:

Dennis,
I have attached an example with more debugging output.
Please test and send back output.

Achim


#------usage example--------------
use strict;

use Authen::SASL 2.10;
use Net::POP3 2.28;

#----Adjust to your environment------
my $pop3host = 'moerbsen.grolmsnet.lan';
#----/Adjust to your environment------

my $sasl = Authen::SASL->new( mechanism => 'GSSAPI' )

|| die 'cannot create SASL object';

#----Just debugging, not needed-----
my $client = $sasl->client_new( 'pop3', $pop3host );
$client->client_start();
print $sasl->error();
#----/Just debugging, not needed-----

my $pop = Net::POP3->new( $pop3host ) || die "can not connect to $pop3host ";
if ( $pop->auth($sasl) ) {
my $msgnums = $pop->list; # hashref of msgnum => size
foreach my $msgnum (keys %$msgnums) {
my $msg = $pop->get($msgnum);
print @$msg;
}
}
else {
die "\n Authentication error from SASL: \n",

$sasl->error,

Graham Barr

unread,
May 22, 2006, 4:08:01 PM5/22/06
to ac...@grolmsnet.de, Dennis Putnam, perl...@perl.org
On Mon, May 22, 2006 1:27 pm, Achim Grolms wrote:
> On Monday 22 May 2006 19:50, Dennis Putnam wrote:
>> Doesn't work. Nothing is in '$!' but the POP log says "badlogin".
>
> Try if this works:

I would not expect it to, as-is. The structure is right, but it needs
authentication details to be added. But my knowledge of how GSSAPI works
and what parameters are needed for it to validate is very limited.

Graham.

Achim Grolms

unread,
May 22, 2006, 4:12:58 PM5/22/06
to Graham Barr, Dennis Putnam, perl...@perl.org
On Monday 22 May 2006 22:08, Graham Barr wrote:
> On Mon, May 22, 2006 1:27 pm, Achim Grolms wrote:
> > On Monday 22 May 2006 19:50, Dennis Putnam wrote:
> >> Doesn't work. Nothing is in '$!' but the POP log says "badlogin".
> >
> > Try if this works:
>
> I would not expect it to, as-is. The structure is right, but it needs
> authentication details to be added.

The Authen::SASL::Perl::GSSAPI module needs
a properly confugurd Kerberosinstallation and a successfull kinit.
All work is done by the Kerberosimplementation.
What details are missing?


Achim

Graham Barr

unread,
May 22, 2006, 4:32:50 PM5/22/06
to ac...@grolmsnet.de, Graham Barr, Dennis Putnam, perl...@perl.org

Ah, I was not aware it did all that behind the scenes.

> What details are missing?

In that case, nothing :-)

Graham.


Achim Grolms

unread,
Jun 6, 2006, 10:17:49 AM6/6/06
to Quanah Gibson-Mount, perl...@perl.org
On Thursday 18 May 2006 18:14, Quanah Gibson-Mount wrote:
> --On Thursday, May 18, 2006 7:27 AM -0400 Dennis Putnam
>
> <dennis...@aimaudit.com> wrote:

[...Net::POP3...]

> I was able to use Authen::SASL to do GSSAPI authentication via finger &
> whois, using the Authen-SASL-GSSAPI-server package.

Net::POP3 2.28

accepts SASL objects for doing SASL authentication and plays
together with Authen::SASL::Perl::GSSAPI.

The problem was that Net::POP3 2.28 uses the wrong servivename 'pop3'
in

| my $client = $sasl->client_new('pop3',${*$self}{'net_pop3_host'},0);

what makes GSSAPI fail because the servivcename is part of the principal
( "pop3/theserver.domain.tld" for example) and a principal
"pop3/theserver.domain.tld" does not exist
in KDC database.

Correct is 'pop' instead as specified in
<http://www.iana.org/assignments/gssapi-service-names>.

That means only

| my $client = $sasl->client_new('pop',${*$self}{'net_pop3_host'},0);

works when connecting to a POP3 server.

Achim

0 new messages