Commit 292e0a09 authored by Leigh Stoller's avatar Leigh Stoller

Checkpoint

parent 78f8781f
......@@ -2601,7 +2601,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
bugdb/GNUmakefile bugdb/bugdbproxy \
protogeni/GNUmakefile protogeni/security/GNUmakefile \
protogeni/xmlrpc/GNUmakefile protogeni/lib/GNUmakefile \
protogeni/scripts/GNUmakefile \
protogeni/scripts/GNUmakefile protogeni/etc/GNUmakefile \
collab/GNUmakefile \
collab/trac/GNUmakefile \
collab/jabber/GNUmakefile \
......
......@@ -970,7 +970,7 @@ outfiles="$outfiles Makeconf GNUmakefile \
bugdb/GNUmakefile bugdb/bugdbproxy \
protogeni/GNUmakefile protogeni/security/GNUmakefile \
protogeni/xmlrpc/GNUmakefile protogeni/lib/GNUmakefile \
protogeni/scripts/GNUmakefile \
protogeni/scripts/GNUmakefile protogeni/etc/GNUmakefile \
collab/GNUmakefile \
collab/trac/GNUmakefile \
collab/jabber/GNUmakefile \
......
......@@ -11,7 +11,7 @@ SUBDIR = protogeni
include $(OBJDIR)/Makeconf
SUBDIRS = security xmlrpc lib scripts
SUBDIRS = security xmlrpc lib scripts etc
all: all-subdirs
......@@ -22,6 +22,7 @@ install:
@$(MAKE) -C xmlrpc install
@$(MAKE) -C lib install
@$(MAKE) -C scripts install
@$(MAKE) -C etc install
control-install:
......
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# All rights reserved.
#
SRCDIR = @srcdir@
TESTBED_SRCDIR = @top_srcdir@
OBJDIR = ../..
SUBDIR = protogeni/etc
include $(OBJDIR)/Makeconf
ETCFILES = geniuser.xml geniproj.xml
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(ETCFILES)
include $(TESTBED_SRCDIR)/GNUmakerules
install: $(addprefix $(INSTALL_ETCDIR)/protogeni/, $(ETCFILES))
control-install:
clean:
rm -f *.o core *.pl *.pm *.py $(ETCFILES)
$(INSTALL_ETCDIR)/protogeni/%: %
@echo "Installing $<"
-mkdir -p $(INSTALL_ETCDIR)/protogeni
$(INSTALL) $< $@
<project>
<attribute name="leader"> <value>geniuser</value></attribute>
<attribute name="name"> <value>GeniSlices</value></attribute>
<attribute name="short description"> <value>Holding Project for geni slices -- DO NOT DELETE</value></attribute>
<attribute name="URL"> <value>@TBDOCBASE@</value></attribute>
<attribute name="members"> <value>1</value></attribute>
<attribute name="num_pcs"> <value>1</value></attribute>
<attribute name="long description"> <value>DO NOT DELETE THIS PROJECT</value></attribute>
<attribute name="funders"> <value>none</value></attribute>
<attribute name="whynotpublic"> <value></value></attribute>
<attribute name="public"> <value>1</value></attribute>
<attribute name="linkedtous"> <value>1</value></attribute>
</project>
<user>
<attribute name="name"> <value>Geni User</value></attribute>
<attribute name="email"> <value>@TBOPSEMAIL_NOSLASH@</attribute>
<attribute name="address"> <value>DO NOT DELETE THIS USER</value></attribute>
<attribute name="address2"> <value>DO NOT DELETE THIS USER</value></attribute>
<attribute name="city"> <value>Any Town</value></attribute>
<attribute name="state"> <value>SS</value></attribute>
<attribute name="zip"> <value>00000</value></attribute>
<attribute name="country"> <value>USA</value></attribute>
<attribute name="phone"> <value>555-555-5555</value></attribute>
<attribute name="shell"> <value>tcsh</value></attribute>
<attribute name="title"> <value>Geni User</value></attribute>
<attribute name="affiliation"> <value>Any U</value></attribute>
<attribute name="password"> <value>*</value></attribute>
<attribute name="wikiname"> <value>GeniUser</value></attribute>
<attribute name="login"> <value>geniuser</value></attribute>
</user>
......@@ -78,7 +78,7 @@ CREATE TABLE `geni_authorities` (
`uuid` varchar(40) NOT NULL default '',
`uuid_prefix` varchar(12) NOT NULL default '',
`created` datetime default NULL,
`type` enum('sa','ma','ch') NOT NULL default 'sa',
`type` enum('sa','cm','ma','ch') NOT NULL default 'sa',
`url` tinytext,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
......
......@@ -12,14 +12,14 @@ SUBDIR = protogeni/lib
include $(OBJDIR)/Makeconf
LIB_SCRIPTS = GeniDB.pm GeniUser.pm GeniSAClient.pm \
GeniSlice.pm GeniSA.pm GeniCM.pm GeniCMClient.pm \
GeniSlice.pm GeniSA.pm GeniCM.pm \
GeniTicket.pm GeniSliver.pm GeniCredential.pm \
GeniComponent.pm GeniCH.pm GeniCHClient.pm GeniEmulab.pm \
GeniAuthority.pm GeniCertificate.pm GeniAggregate.pm \
GeniUtil.pm GeniRegistry.pm
SBIN_SCRIPTS = plabnodewrapper plabslicewrapper
SCRIPTS = test.pl addnode.pl test.pl addauthority regtest.pl
SCRIPTS = test.pl addnode.pl test.pl addauthority
OPS_LIBS = GeniCMClient.pm GeniSAClient.pm GeniCHClient.pm
# These scripts installed setuid, with sudo.
......
......@@ -19,6 +19,7 @@ use vars qw(@ISA @EXPORT);
# Must come after package declaration!
use lib '@prefix@/lib';
use GeniDB;
use GeniRegistry;
use libtestbed;
use libdb qw(TBGetUniqueIndex);
use English;
......@@ -124,7 +125,7 @@ sub Stringify($)
#
# Create a Geni authority in the DB.
#
sub Create($$$$$$)
sub Create($$$$)
{
my ($class, $certificate, $url, $type) = @_;
......@@ -170,6 +171,40 @@ sub type($) { return field($_[0], "type"); }
sub cert($) { return $_[0]->{'CERT'}->cert(); }
sub GetCertificate($) { return $_[0]->{'CERT'}; }
#
# Check to see if there is an existing authority with the same prefix.
#
sub CheckExisting($$$$)
{
my ($class, $type, $uuid, $hrn) = @_;
my ($prefix) = ($certificate->uuid() =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/);
my $query_result =
DBQueryWarn("select uuid,type from geni_authorities ".
"where uuid_prefix='$prefix'");
return -1
if (!$query_result);
return 0
if (!$query_result->numrows);
while (my ($DBuuid,$DBtype) = $query_result->fetchrow_array()) {
# Look for an exact match, which means its just a replacement.
next
if ($uuid eq $DBuuid && $type eq $DBtype);
# Same uuid, different type.
return 1
if ($uuid eq $DBuuid && $type ne $DBtype);
# Different uuid, same type.
return 1
if ($uuid ne $DBuuid && $type eq $DBtype);
}
return 0;
}
#
# Create authority from the ClearingHouse, by looking up the info.
#
......@@ -177,9 +212,13 @@ sub CreateFromRegistry($$$)
{
my ($class, $type, $uuid) = @_;
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
if (!defined($clearinghouse));
my $blob;
return undef
if (GeniCHClient::Resolve($uuid, $type, \$blob) != 0);
if ($clearinghouse->Resolve($uuid, $type, \$blob) != 0);
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
......
......@@ -212,6 +212,16 @@ sub Resolve($)
};
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
if ($type eq "MA") {
#
# I think the MA is the ClearingHouse?
#
# Return a blob.
my $blob = { "gid" => $authority->cert(),
"url" => $authority->url(),
};
return GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
}
if ($type eq "Slice") {
my $slice = GeniSlice->Lookup($uuid);
if (!defined($slice)) {
......@@ -250,7 +260,7 @@ sub Register($)
my $info = $argref->{'info'};
my $type = $argref->{'type'};
if (! (defined($type) && ($type =~ /^(SA|MA|Component|Slice|User)$/))) {
if (! (defined($type) && ($type =~ /^(SA|MA|CM|Component|Slice|User)$/))) {
return GeniResponse->MalformedArgsResponse();
}
if (! defined($cred)) {
......@@ -515,8 +525,27 @@ sub Register($)
return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
"Could not register new resource");
}
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
}
if ($type eq "CM" || $type eq "SA") {
my $url = $info->{'url'};
#
# Check for an existing authority.
#
if (GeniAuthority->CheckExisting($certificate->uuid(), $type,
$certificate->hrn()) != 0) {
print STDERR "Attempt to register existing authority\n";
return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
"Authority already exists");
}
my $authority = GeniAuthority->Create($certificate, $url, $type);
if (!defined($authority)) {
print STDERR "Could not register new authority\n";
return GeniResponse->Create(GENIRESPONSE_ERROR);
}
return GeniResponse->Create(GENIRESPONSE_SUCCESS);
}
return GeniResponse->Create(GENIRESPONSE_UNSUPPORTED);
}
......@@ -530,7 +559,7 @@ sub Remove($)
my $uuid = $argref->{'uuid'};
my $type = $argref->{'type'};
if (! (defined($type) && ($type =~ /^(SA|MA|Component|Slice|User)$/))) {
if (! (defined($type) && ($type =~ /^(SA|MA|CM|Component|Slice|User)$/))) {
return GeniResponse->MalformedArgsResponse();
}
if (! defined($cred)) {
......
......@@ -30,6 +30,7 @@ use GeniAggregate;
use GeniAuthority;
use GeniSliver;
use GeniUser;
use GeniRegistry;
use libtestbed;
# Hate to import all this crap; need a utility library.
use libdb qw(TBGetUniqueIndex TBcheck_dbslot TBDB_CHECKDBSLOT_ERROR);
......@@ -1158,10 +1159,14 @@ sub CreateAuthorityFromRegistry($)
my ($uuid) = @_;
my ($prefix) = ($uuid =~ /^\w+\-\w+\-\w+\-\w+\-(\w+)$/);
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
if (!defined($clearinghouse));
my $blob;
return undef
if (GeniCHClient::Resolve("P${prefix}", "SA", \$blob) != 0);
if ($clearinghouse->Resolve("P${prefix}", "SA", \$blob) != 0);
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
......@@ -1415,7 +1420,7 @@ sub GeniExperiment($)
}
#
# Return a list of slivers for the specified slice.
# Return the top level aggregate (sliver) for a slice.
#
sub GetSliver($)
{
......
......@@ -329,9 +329,11 @@ sub WriteToFile($)
print $tempfile "-----BEGIN CERTIFICATE-----\n";
print $tempfile $self->cert();
print $tempfile "-----END CERTIFICATE-----\n";
print $tempfile "-----BEGIN RSA PRIVATE KEY-----\n";
print $tempfile $self->privkey();
print $tempfile "-----END RSA PRIVATE KEY-----\n";
if ($self->privkey()) {
print $tempfile "-----BEGIN RSA PRIVATE KEY-----\n";
print $tempfile $self->privkey();
print $tempfile "-----END RSA PRIVATE KEY-----\n";
}
return $filename;
}
......
......@@ -21,6 +21,7 @@ use lib '@prefix@/lib';
use GeniDB;
use Genixmlrpc;
use GeniResponse;
use GeniRegistry;
use GeniTicket;
use GeniCredential;
use libdb qw(TBGetUniqueIndex);
......@@ -279,9 +280,13 @@ sub CreateFromRegistry($$)
{
my ($class, $uuid) = @_;
my $clearinghouse = GeniRegistry::ClearingHouse->Create();
return undef
if (!defined($clearinghouse));
my $blob;
return undef
if (GeniCHClient::Resolve($uuid, "CM", \$blob) != 0);
if ($clearinghouse->Resolve($uuid, "CM", \$blob) != 0);
my $certificate = GeniCertificate->LoadFromString($blob->{'gid'});
return undef
......
......@@ -262,9 +262,21 @@ sub Create($;$$)
my $EMULAB_PEMFILE1 = "@prefix@/etc/genima.pem";
my $EMULAB_PEMFILE2 = "@prefix@/etc/genich.pem";
my $pemfile = (-e $EMULAB_PEMFILE1 ? $EMULAB_PEMFILE1 : $EMULAB_PEMFILE2);
if (!defined($credential)) {
my $pemfile;
if (-e $EMULAB_PEMFILE1) {
$pemfile = $EMULAB_PEMFILE1
}
elsif (-e $EMULAB_PEMFILE2) {
$pemfile = $EMULAB_PEMFILE2;
}
else {
print STDERR "Cannot find the pem file for the clearinghouse!\n";
retrn undef;
}
#
# We are creating a self signed credential here, which is fine
# since the Clearinghouse has the certs of all trusted roots.
......@@ -298,5 +310,22 @@ sub Create($;$$)
$context, $credential->asString());
}
#
# Get a credential from the clearinghouse, as for bootstrapping.
#
sub GetCredential($;$)
{
my ($class, $context) = @_;
my $response =
Genixmlrpc::CallMethod($GENICENTRALURL, $context, "GetCredential", {});
return undef
if (!defined($response) ||
$response->code() != GENIRESPONSE_SUCCESS);
return GeniCredential->CreateFromSigned($response->value(), 1);
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -959,7 +959,7 @@ sub Start($)
# XXX Need to fix up this status stuff.
if ($node->isremotenode() && $self->status() eq "created") {
$self->SetStatus("ready");
next;
goto done;
}
#
......@@ -983,6 +983,7 @@ sub Start($)
# Signal error so we can look at what happened.
return -1;
}
done:
return 0;
}
......
......@@ -225,11 +225,13 @@ sub Create($$$$;$)
push(@insert_data, "sa_uuid='$sa_uuid'");
#
# uid come from last component of the hrn.
# uid comes from last component of the hrn.
#
my ($uid) = ($certificate->hrn() =~ /^.*\.(\w*)$/);
return undef
if (!defined($uid));
if (!defined($uid)) {
print STDERR "HRN is not dotted: " . $certificate->hrn() . "\n";
return undef;
}
#
# This comes from either an info record or the cert.
......
......@@ -78,7 +78,7 @@ CREATE TABLE `geni_authorities` (
`uuid` varchar(40) NOT NULL default '',
`uuid_prefix` varchar(12) NOT NULL default '',
`created` datetime default NULL,
`type` enum('sa','ma','ch') NOT NULL default 'sa',
`type` enum('sa','cm','ma','ch') NOT NULL default 'sa',
`url` tinytext,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
......
......@@ -11,7 +11,9 @@ SUBDIR = protogeni/scripts
include $(OBJDIR)/Makeconf
SBIN_STUFF = newgeninode cleanupslice register_resources
SBIN_STUFF = cleanupslice
PSBIN_STUFF = newgeninode register_resources \
createcerts initsite addauthority
# These scripts installed setuid, with sudo.
SETUID_BIN_SCRIPTS =
......@@ -22,14 +24,20 @@ SETUID_LIBX_SCRIPTS =
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(SBIN_STUFF)
all: $(SBIN_STUFF) $(PSBIN_STUFF)
include $(TESTBED_SRCDIR)/GNUmakerules
install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_STUFF))
install: $(addprefix $(INSTALL_SBINDIR)/, $(SBIN_STUFF)) \
$(addprefix $(INSTALL_SBINDIR)/protogeni/, $(PSBIN_STUFF))
control-install:
clean:
rm -f *.o core *.pl *.pm *.py
rm -f *.o core *.pl *.pm *.py $(SBIN_STUFF) $(PSBIN_STUFF)
$(INSTALL_SBINDIR)/protogeni/%: %
@echo "Installing $<"
-mkdir -p $(INSTALL_SBINDIR)/protogeni
$(INSTALL) $< $@
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2008 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
use Data::Dumper;
use Getopt::Std;
#
# Add an authority to the DB. Mostly for bootstrapping.
#
sub usage()
{
print "Usage: addauthority [-c]\n";
exit(1);
}
my $optlist = "c";
my $asch = 0;
use vars qw($GENI_DBNAME);
if ($asch) {
$GENI_DBNAME = "geni-ch";
}
# Now we can load the libraries after setting the proper DB.
use lib '@prefix@/lib';
require GeniDB;
use GeniCertificate;
use GeniAuthority;
#
# Check args.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"c"})) {
$asch = 1;
}
usage()
if (@ARGV != 3);
my $certfile = $ARGV[0];
my $type = $ARGV[1];
my $url = $ARGV[2];
my $certificate = GeniCertificate->LoadFromFile($certfile);
if (!defined($certificate)) {
die("Could not get certificate from $certfile\n");
}
if ($certificate->uuid() =~ /\w*-(\w*)$/) {
$prefix = $1;
}
else {
die("Could not get prefix from uuid\n");
}
if (GeniAuthority->CheckExisting($type, $certificate->uuid(),
$certificate->hrn())) {
die("$certfile is already registered in the DB\n");
}
GeniAuthority->Create($certificate, $url, $prefix, $type)
or die("Could not add new authority\n");
exit(0);
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2008 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
use Getopt::Std;
#
# Create the certs for a new protogeni emulab. Add optional -c option if
# this is a clearinghouse.
#
sub usage()
{
print "Usage: createpgenicerts [-c]\n";
exit(1);
}
my $optlist = "c";
my $asch = 0;
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $PGENIDOMAIN = "@PROTOGENI_DOMAIN@";
my $PGENISUPPORT = @PROTOGENI_SUPPORT@;
my $TBBASE = "@TBBASE@";
my $mksyscert = "$TB/sbin/mksyscert";
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/site/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Protos
sub fatal($);
#
# Turn off line buffering on output
#
$| = 1;
# Load the Testbed support stuff.
use lib "@prefix@/lib";
use libdb;
use libtestbed;
if ($UID != 0) {
fatal("Must be root to run this script\n");
}
#
# Check args.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"c"})) {
$asch = 1;
}
#
# Generate the certs we need.
#
system("$mksyscert -o /tmp/genicm.pem ".
" -u $TBBASE/protogeni/xmlrpc/cm $PGENIDOMAIN.cm") == 0
or fatal("Could not generate CM certificate");
system("$mksyscert -o /tmp/genisa.pem ".
" -u $TBBASE/protogeni/xmlrpc/sa $PGENIDOMAIN.sa") == 0
or fatal("Could not generate SA certificate");
if ($asch) {
system("$mksyscert -o /tmp/genich.pem ".
" -u $TBBASE/protogeni/xmlrpc/ch $PGENIDOMAIN.ch") == 0
or fatal("Could not generate CH certificate");
}
exit(0);
sub fatal($)
{
my ($msg) = @_;
die("*** $0:\n".
" $msg\n");
}
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2008 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
use Getopt::Std;
#
# Initialize an emulab to act as a protogeni emulab. Add optional -c
# option if this is a clearinghouse.
#
sub usage()
{
print "Usage: initpgenisite [-c]\n";
exit(1);
}
my $optlist = "c";
my $asch = 0;
my $cflag = "";
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $TBLOGS = "@TBLOGSEMAIL@";
my $PGENIDOMAIN = "@PROTOGENI_DOMAIN@";
my $PGENISUPPORT = @PROTOGENI_SUPPORT@;
my $TBBASE = "@TBBASE@";
my $newuser = "$TB/sbin/newuser";
my $newproj = "$TB/sbin/newproj";
my $tbacct = "$TB/sbin/tbacct";
my $mkcerts = "$TB/sbin/protogeni/createcerts";
my $addauthority = "$TB/sbin/protogeni/addauthority";
my $SACERT = "$TB/etc/genisa.pem";
my $CMCERT = "$TB/etc/genicm.pem";
my $CHCERT = "$TB/etc/genich.pem";
my $SUDO = "/usr/local/bin/sudo";
my $MYSQL = "/usr/local/bin/mysql";
my $MYSQLADMIN = "/usr/local/bin/mysqladmin";
my $MYSQLSHOW = "/usr/local/bin/mysqlshow";
my $MYSQLDUMP = "/usr/local/bin/mysqldump";
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/site/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Protos
sub fatal($);
#
# Turn off line buffering on output
#
$| = 1;
# Load the Testbed support stuff.
use lib "@prefix@/lib";
use Genixmlrpc;
use GeniRegistry;
if ($UID != 0) {
fatal("Must be root to run this script\n");
}
#
# Check args.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"c"})) {
$asch = 1;
$cflag = "-c";
}
#
# The web server needs to do client authentication, for the geni xmlrpc
# interface. A bundle of CA certs from the trusted roots (emulabs) will
# be used. This bundle will periodically update as sites come online.
# To start with, its just the local CA cert. Please make sure that
# /etc/rc.conf has this line in it:
#
# apache_flags="-DSSL -DPGENI"
#
if (! -e "$TB/etc/genica.bundle") {
system("/bin/cp $TB/etc/emulab.pem $TB/etc/genica.bundle") == 0
or fatal("Could not initialize $TB/etc/genica.bundle");
}
if (system("egrep -q -s 'DPGENI' /etc/rc.conf")) {
print "Please add 'apache_flags=\"-DSSL -DPGENI\"' to /etc/rc.conf\n";
print "Then restart apache. Then rerun this script\n";
exit(1);
}
#
# user/project that slices (experiments) belong to.
#
#
# Databases.
#
#
# Generate the certs we need.
#
system("$mkcerts $cflag") == 0
or fatal("Could not generate certificates");