Skip to content

Commit

Permalink
Support download using Kerbeors authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
stdweird committed Mar 25, 2016
1 parent 22662f9 commit c12df06
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 9 deletions.
20 changes: 16 additions & 4 deletions src/main/bin/ccm-fetch
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ sub app_options {
HELP => 'Directory containing trusted CA certificates for use with HTTPS' },

{ NAME => 'trust=s',
HELP => 'Kerberos principal to trust if using encrypted profiles' },
HELP => 'Comma-separated list of Kerberos principals to trust if using encrypted profiles' },

{ NAME => 'keep_old=i',
HELP => 'Number of old profiles to keep before purging' },
Expand All @@ -126,9 +126,13 @@ sub app_options {
{ NAME => 'tabcompletion',
HELP => 'Create the tabcompletion file (during profile fetch)' },

{ NAME => 'debug|d=i',
DEFAULT => '0',
HELP => 'Turn on debugging messages' });
{ NAME => 'principal=s',
HELP => 'Principal to use for Kerberos setup' },

{ NAME => 'keytab=s',
HELP => 'Keytab to use for Kerberos setup' },

);

return \@options;
}
Expand Down Expand Up @@ -269,6 +273,14 @@ $fetch->setContextnTime($this_app->option("context_time"))
$fetch->setContext($this_app->option("context"))
if defined $this_app->option("context");

# set principal
$fetch->setPrincipal($this_app->option("principal"))
if defined $this_app->option("principal");

# set keytab
$fetch->setKeytab($this_app->option("keytab"))
if defined $this_app->option("keytab");

#fetch rpofile
my $errno = $fetch->fetchProfile();

Expand Down
2 changes: 1 addition & 1 deletion src/main/conf/quattor-ccm
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ _quattor_ccm_make_long_options()
}

# sorted list of options for CCM::Options based tools
_quattor_ccm_CCfg_options=(base_url cache_root ca_dir ca_file cert_file context dbformat debug force get_timeout group_readable json_typed keep_old key_file lock_retries lock_wait preprocessor profile profile_failover purge_time retrieve_retries retrieve_wait tabcompletion trust world_readable)
_quattor_ccm_CCfg_options=(base_url cache_root ca_dir ca_file cert_file context dbformat debug force get_timeout group_readable json_typed keep_old key_file keytab lock_retries lock_wait preprocessor principal profile profile_failover purge_time retrieve_retries retrieve_wait tabcompletion trust world_readable)

# sorted list of options for CCM::Options based tools
# (except those already in _quattor_ccm_CCfg_options)
Expand Down
15 changes: 14 additions & 1 deletion src/main/perl/CCfg.pm
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Readonly::Array our @CONFIG_OPTIONS => (
{
option => 'trust',
suffix => '=s',
HELP => 'Kerberos principal to trust if using encrypted profiles',
HELP => 'Comma-separated list of kerberos principals to trust when using encrypted profiles',
},

{
Expand Down Expand Up @@ -211,6 +211,19 @@ Readonly::Array our @CONFIG_OPTIONS => (
DEFAULT => 0,
HELP => 'Create the tabcompletion file (during profile fetch)',
},

{
option => 'principal',
suffix => '=s',
HELP => 'Principal to use for Kerberos setup',
},

{
option => 'keytab',
suffix => '=s',
HELP => 'Keytab to use for Kerberos setup',
},

);

Readonly::Array our @CFG_KEYS => sort map {$_->{option}} @CONFIG_OPTIONS;
Expand Down
17 changes: 17 additions & 0 deletions src/main/perl/Fetch/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,23 @@ sub setProfileFailover
return SUCCESS;
}

sub setPrincipal
{
my ($self, $val) = @_;
throw_error("Invalid characters in principal: $val")
unless ($val =~ m/^[\w.-\/@]+$/);
$self->{PRINCIPAL} = $val;
return SUCCESS;
}

sub setKeytab
{
my ($self, $val) = @_;
throw_error("Keytab $val not readable") unless (-r $val);
$self->{KEYTAB} = $val;
return SUCCESS;
}

sub getCacheRoot
{
my ($self) = @_;
Expand Down
26 changes: 24 additions & 2 deletions src/main/perl/Fetch/Download.pm
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ use Compress::Zlib;
use LC::Stat qw(:ST);

use GSSAPI;
use CAF::Kerberos 16.2.1;

use LWP::UserAgent;
use LWP::Authen::Negotiate;
use HTTP::Request;


# LWP should use Net::SSL (provided with Crypt::SSLeay)
# and Net::SSL doesn't support hostname verify
$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = 'Net::SSL';
Expand Down Expand Up @@ -70,6 +73,23 @@ sub retrieve
{
my ($self, $url, $cache, $time) = @_;

my ($cnt, $krb);
if ($self->{PRINCIPAL}) {
$self->verbose("PRINCIPAL $self->{PRINCIPAL} configured, setting up Kerberos environment");
my $krb_opts = {
principal => $self->{PRINCIPAL},
log => $self,
};
$krb_opts->{keytab} = $self->{KEYTAB} if $self->{KEYTAB};
$krb = CAF::Kerberos->new(%$krb_opts);

return if(! defined($krb->get_context()));

# set environment to temporary credential cache
# temporary cache is cleaned-up during destroy of $krb
$krb->update_env(\%ENV);
};

my $ua = LWP::UserAgent->new();
my $rq = HTTP::Request->new(GET => $url);

Expand All @@ -92,10 +112,12 @@ sub retrieve
return;
}

my $cnt;
if ($rs->content_encoding() && $rs->content_encoding() eq 'krbencrypt') {
my ($author, $payload) = $self->_gss_decrypt($rs->content());
if ($self->{TRUST} && !grep($author =~ $_, @{$self->{TRUST}})) {
# TODO: if no trusts are configured, do you really just trust anything you can decrypt
# TODO: The old code made no sense, $self->{TRUST} can be an empty arrayref and is thus always true
my @trusts = @{$self->{TRUST} || []};
if (@trusts && ! grep($author =~ $_, @trusts)) {
die("Refusing profile generated by $author");
}
$cnt = $payload;
Expand Down
4 changes: 3 additions & 1 deletion src/test/perl/test-ccfg.t
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,11 @@ Readonly::Hash my %DEFAULT_CFG => {
"json_typed" => 0,
"keep_old" => 2,
"key_file" => undef,
"keytab" => undef,
"lock_retries" => 3,
"lock_wait" => 30,
"preprocessor" => undef,
"principal" => undef,
"profile" => undef,
"profile_failover" => undef,
"purge_time" => 86400,
Expand All @@ -203,7 +205,7 @@ is($CONFIG_FN, "/etc/ccm.conf", "Expected default ccm config file");
# Hard test for possible values (sorted)
is_deeply(\@CFG_KEYS, [qw(base_url ca_dir ca_file cache_root cert_file
context dbformat debug force get_timeout group_readable json_typed keep_old
key_file lock_retries lock_wait preprocessor profile profile_failover
key_file keytab lock_retries lock_wait preprocessor principal profile profile_failover
purge_time retrieve_retries retrieve_wait tabcompletion trust world_readable
)], "CFG_KEYS exports all possible configuration keys");

Expand Down

0 comments on commit c12df06

Please sign in to comment.