Commit 671aa419 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Add "restricted" argument to share vlan method. When restricted we mint

a credential to return the user, and we require that credential on
subsequent attempts to link to that shared vlan. It is assumed that the
caller knows how to delegate the credential if necessary.
parent 04c54aa1
......@@ -1148,7 +1148,9 @@ sub PerformOperationalAction
$args->{'slice_urn'} = $slice->urn();
$args->{'token'} = $options->{"geni_sharelan_token"};
$args->{'lanname'} = $options->{"geni_sharelan_lanname"};
if (exists($options->{"geni_sharelan_restricted"})) {
$args->{'restricted'} = $options->{"geni_sharelan_restricted"};
}
return GeniCMV2::ShareLan($args);
}
elsif ($action eq 'geni_unsharelan') {
......
......@@ -1869,6 +1869,43 @@ sub GetTicketAuxAux($$$$$$$$$$)
my $encap = "default";
if (my $shared_vlan = GeniXML::GetSharedLanName($linkref)) {
if ($shared_vlan !~ /^[-\w]*$/) {
$response =
GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Invalid shared lan name: $shared_vlan");
goto bad;
}
my $lanref = Lan->LookupSharedVLanByToken($shared_vlan);
if (!defined($lanref)) {
$response =
GeniResponse->Create(GENIRESPONSE_SEARCHFAILED, undef,
"No such shared lan: $shared_vlan");
goto bad;
}
if (!$lanref->{'open'}) {
#
# A closed lan, there needs to be a credential to use it.
#
my $allowed;
foreach my $cred (@$credentials) {
my ($domain, $type, $id) =
GeniHRN::Parse($cred->target_urn());
if ($domain eq $OURDOMAIN && $type eq "vlan" &&
$id == $lanref->{'lanid'}) {
$allowed = $cred;
last;
}
}
if (!defined($allowed)) {
$response =
GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef,
"No permission to use shared lan: $shared_vlan");
goto bad;
}
}
# This is the magic for libvtop.
$virtexperiment->NewTableRow("virt_lan_settings",
{"vname" => $lanname,
......
......@@ -3064,6 +3064,8 @@ sub ShareLanAux($$)
my $credentials = $argref->{'credentials'};
my $linkname = $argref->{'lanname'};
my $token = $argref->{'token'};
my $restricted = (exists($argref->{'restricted'}) &&
$argref->{'restricted'} ? 1 : 0);
require Lan;
......@@ -3136,11 +3138,42 @@ sub ShareLanAux($$)
"Lan is already shared");
}
if (!$revoke) {
my ($lan_cert, $lan_cred);
#
# If the sharing is restricted, we need to mint a credential for
# the user that they can delegate.
#
if ($restricted) {
my $lan_urn = GeniHRN::Generate($OURDOMAIN, "vlan", $vlan->lanid());
my $lan_hrn = "${PGENIDOMAIN}.vlan" . "." . $vlan->lanid();
$lan_cert=
GeniCertificate->Create({"urn" => $lan_urn,
"hrn" => $lan_hrn,
'email' => $TBOPS});
if (!defined($lan_cert)) {
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not create certificate");
}
$lan_cred =
GeniCredential->CreateSigned($lan_cert, $user,
$GeniCredential::LOCALCM_FLAG);
if (!defined($lan_cred)) {
$lan_cert->Delete();
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not create credential");
}
}
#
# This operation has to be done as an admin person.
#
my $opt = ($restricted ? "" : "-o");
GeniUtil::FlipToElabMan();
my $output = GeniUtil::ExecQuiet("$WAP $SHAREVLAN -o $pid,$eid ".
my $output = GeniUtil::ExecQuiet("$WAP $SHAREVLAN $opt $pid,$eid ".
" $linkname $token");
my $ecode = $?;
GeniUtil::FlipToGeniUser();
......@@ -3148,6 +3181,8 @@ sub ShareLanAux($$)
print STDERR "Failed to share vlan:\n";
print STDERR $output;
$slice->UnLock();
$lan_cert->Delete()
if (defined($lan_cert));
return GeniResponse->Create(GENIRESPONSE_ERROR, undef, $output);
}
libtestbed::SENDMAIL($TBOPS, "$linkname has been shared",
......@@ -3158,7 +3193,9 @@ sub ShareLanAux($$)
$TBOPS);
$slice->UnLock();
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
return GeniResponse->Create(GENIRESPONSE_SUCCESS,
defined($lan_cred) ?
$lan_cred->asString() : undef);
}
#
# Revoking is a litte trickier since we have to worry about the
......@@ -3166,6 +3203,14 @@ sub ShareLanAux($$)
# backend program is going to revoke access from all the experiments
# using those ports. Oh well.
#
# Delete certificate (in case it was restricted, see above)
#
my $lan_urn = GeniHRN::Generate($OURDOMAIN, "vlan", $vlan->lanid());
my $lan_cert = GeniCertificate->Lookup($lan_urn);
if (defined($lan_cert)) {
$lan_cert->Delete();
}
# This operation has to be done as an admin person.
#
GeniUtil::FlipToElabMan();
......
......@@ -2048,8 +2048,10 @@ sub LoadVirtLans($)
tberror("Target vlan for $porttoken does not exist!\n");
return -1;
}
# Very primitive access check.
if (! ($rowref->{'open'} || $self->user()->IsAdmin())) {
# Very primitive access check. But not for Geni experiments,
# we made the checks in the CM
if (! ($rowref->{'open'} || $self->user()->IsAdmin() ||
exists($ENV{"GENIURN"}))) {
tberror("Target vlan for $porttoken is not open!\n");
return -1;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment