added the token authentication mechanism in the xcatd

This commit is contained in:
daniceexi 2014-04-07 07:57:57 -04:00
parent d5cb13be6d
commit 6bb22d2342
3 changed files with 110 additions and 1 deletions

View File

@ -1568,7 +1568,18 @@ hwinv => {
disable => "Set to 'yes' or '1' to comment out this row.",
},
},
token => {
cols => [qw(tokenid username expire comments disable)],
keys => [qw(tokenid)],
table_desc => 'The token of users for authentication.',
descriptions => {
tokenid => 'It is a UUID as an unified identify for the user.',
username => 'The user name.',
expire => 'The expire time for this token.',
comments => 'Any user-provided notes.',
disable => "Set to 'yes' or '1' to comment out this row.",
},
},
); # end of tabspec definition

View File

@ -10,6 +10,7 @@ use xCAT::Table;
use xCAT::MsgUtils;
use Data::Dumper;
use xCAT::NodeRange;
use xCAT::Utils;
#--------------------------------------------------------------------------------
=head1 xCAT::XCATD
@ -270,4 +271,67 @@ sub validate {
xCAT::MsgUtils->message("S","Request matched no policy rule: peername=$peername, peerhost=$peerhost ".$request->{command}->[0]);
return 0;
}
my $tokentimeout = 86400; # one day
# this subroutine search the token table
# 1. find the existed token entry for the user and reset the expire time
# 1.1. if not find existed token, create a new one and add it to token table
# 2. clean up the expired token
#
# this subroutine is called after the account has been authorized
sub gettoken {
my $class=shift;
my $req = shift;
my $user = $req->{gettoken}->[0]->{username}->[0];
my $tokentb = xCAT::Table->new('token');
unless ($tokentb) {
return undef;
}
my $tokens = $tokentb->getAllEntries;
my $expiretime = time() + $tokentimeout;
foreach my $token (@{$tokens}) {
if ($token->{username} eq $user) {
#delete old token
$tokentb->delEntries({'tokenid'=>$token->{tokenid}});
} else {
#clean the expired token
if ($token->{expire} > $expiretime) {
$tokentb->delEntries({'tokenid'=>$token->{tokenid}});
}
}
}
# create a new token for this request
my $uuid = xCAT::Utils->genUUID();
$tokentb->setAttribs({tokenid=>$uuid, username => $user}, {expire => $expiretime});
$tokentb->close();
return ($uuid, $expiretime);
}
# verify the token has correct entry in token table and expire time is not exceeded.
sub verifytoken {
my $class=shift;
my $req = shift;
my $tokenid = $req->{tokens}->[0]->{tokenid}->[0];
my $tokentb = xCAT::Table->new('token');
unless ($tokentb) {
return undef;
}
my $token = $tokentb->getAttribs({'tokenid' => $tokenid}, ('username', 'expire'));
if (defined ($token) && defined ($token->{'username'}) && defined ($token->{'expire'})) {
my $expiretime = time() + $tokentimeout;
if ($token->{'expire'} < time()) {
$tokentb->delEntries({'tokenid'=>$token->{tokenid}});
return undef;
} else {
return $token->{'username'};
}
} else {
return undef;
}
}
1;

View File

@ -2096,6 +2096,40 @@ sub service_connection {
delete($req->{becomeuser}); #Remove it to keep it from view
}
# If the request is to aquire a token for a specific account
if (defined $req->{gettoken}) {
# authencitate the username:password
$peername=becomeuser($req->{gettoken}->[0]->{username}->[0],
$req->{gettoken}->[0]->{password}->[0]);
my $resp;
if ($peername) {
# for a valid account, get a token
my ($tokenid, $exptime) = xCAT::xcatd->gettoken($req);
my ($sec,$min,$hour,$mday,$mon,$year) = localtime($exptime);
$year += 1900;
my $htime = "$year-$mon-$mday $hour:$min:$sec";
$resp = {data=>[{token => [{id => $tokenid, expire => $htime}]}]};
} else {
$resp={error=>["Authentication failure"],errorcode=>[1]};
}
$resp->{serverdone}=[ undef ] ;
send_response($resp,$sock);
return;
}
# If user trying to use 'token' to authenticate
if (defined $req->{tokens}) {
# get the valid user name by the token id
$peername = xCAT::xcatd->verifytoken($req);
unless (defined $peername) {
my $resp={error=>["Authentication failure"],errorcode=>[1]};
$resp->{serverdone}=[ undef ] ;
send_response($resp,$sock);
return;
}
delete($req->{tokenid});
}
#we have a full request..
#printf $request."\n";
$request="";