Commit 61e67aa0 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Checkpoint.

parent c7d44ae3
......@@ -11,7 +11,7 @@ SUBDIR = protogeni
include $(OBJDIR)/Makeconf
SUBDIRS = security
SUBDIRS = security xmlrpc
all: all-subdirs
......@@ -19,6 +19,7 @@ include $(TESTBED_SRCDIR)/GNUmakerules
install:
@$(MAKE) -C security install
@$(MAKE) -C xmlrpc install
control-install:
......
......@@ -73,7 +73,7 @@ my $sigtmpl =
" Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>\n".
" <SignatureMethod ".
" Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>\n".
" <Reference URI=\"%s\">\n".
" <Reference URI=\"#%s\">\n".
" <Transforms>\n".
" <Transform ".
" Algorithm=\"http://www.w3.org/2000/09/xmldsig#".
......@@ -204,6 +204,12 @@ my $root = $doc->documentElement();
$keyfile = $EMULAB_KEY;
$certfile = $EMULAB_CERT;
#
# Find or create these two nodes.
#
my $credentials_node;
my $signatures_node;
#
# Check the root.
#
......@@ -220,40 +226,46 @@ if ($root->nodeName eq "credential") {
# </signatures>
# </signed-credential>
#
my $newroot = XML::LibXML::Element->new('signed-credential');
my $signatures_node = XML::LibXML::Element->new('signatures');
my $newroot = XML::LibXML::Element->new('signed-credential');
$signatures_node = XML::LibXML::Element->new('signatures');
$credentials_node = $root;
$newroot->addChild($root);
$newroot->addChild($signatures_node);
#
# We need the id of the toplevel credential so that we can stick
# it into the sig template above, in the References section. We
# also need to generate an id for the signature node so that we
# can find it and tell xmlsec about it.
#
my ($xmlid_attribute) = $root->attributes();
my $xmlid = $xmlid_attribute->getValue();
$sigid = "Sig_${xmlid}";
my $template = sprintf($sigtmpl, $sigid, $xmlid);
#
# Convert the template above into a document tree and add it to the
# signatures list.
#
my $tmpparser = XML::LibXML->new;
my $newdoc = $tmpparser->parse_string($template);
my $sigroot = $newdoc->documentElement();
$sigroot->setNamespace("http://www.w3.org/2000/09/xmldsig#");
$signatures_node->addChild($sigroot);
$root = $newroot;
$doc->setDocumentElement($root);
print $root->toString(1) . "\n";
#print $root->toString(1) . "\n";
}
else {
;
($credentials_node) = $root->getElementsByTagName("credential");
($signatures_node) = $root->getElementsByTagName("signatures");
if (! (defined($credentials_node) && defined($signatures_node))) {
fatal("Malformed signed credentials input");
}
}
#
# We need the id of the toplevel credential so that we can stick
# it into the sig template above, in the References section. We
# also need to generate an id for the signature node so that we
# can find it and tell xmlsec about it.
#
my ($xmlid_attribute) = $credentials_node->attributes();
my $xmlid = $xmlid_attribute->getValue();
$sigid = "Sig_${xmlid}";
my $template = sprintf($sigtmpl, $sigid, $xmlid);
#
# Convert the template above into a document tree and add it to the
# signatures list.
#
my $tmpparser = XML::LibXML->new;
my $newdoc = $tmpparser->parse_string($template);
my $sigroot = $newdoc->documentElement();
$sigroot->setNamespace("http://www.w3.org/2000/09/xmldsig#");
$signatures_node->addChild($sigroot);
#
# So now we have a valid document that needs to be signed at the $sigid
# reference point. Must write this to a tmp file for xmlsec, and then
......@@ -265,14 +277,25 @@ print TMP $doc->toString(1) . "\n";
close(TMP);
# Fire up xmlsec and read back the results.
my $signedcred = "";
open(SEC, "$XMLSEC1 --sign --node-id $sigid ".
" --privkey-pem $keyfile,$certfile $tmpfile |")
or fatal("Could not start $XMLSEC1 on $tmpfile");
while (<SEC>) {
print $_;
$signedcred .= $_;
}
close(SEC);
if (!defined($outfile)) {
print $signedcred;
}
else {
open(TMP, ">$outfile") or
fatal("Could not open $outfile");
print TMP $signedcred;
close(TMP);
}
cleanup();
exit(0);
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<credential xml:id="Ref1">
<type>capability</type>
<owner_uuid>foo bar</owner_uuid>
<this_uuid>foo bar</this_uuid>
<capabilities>
<capability>
<capability_name>frazzle</capability_name>
<can_delegate>1</can_delegate>
</capability>
</capabilities>
</credential>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<signed-credential>
<credential xml:id="Ref2">
<type>capability</type>
<owner_uuid>foo bar</owner_uuid>
<this_uuid>foo bar</this_uuid>
<capabilities>
<capability>
<capability_name>frazzle</capability_name>
<can_delegate>1</can_delegate>
</capability>
</capabilities>
<parent>
<credential xml:id="Ref1">
<type>capability</type>
<owner_uuid>foo bar</owner_uuid>
<this_uuid>foo bar</this_uuid>
<capabilities>
<capability>
<capability_name>frazzle</capability_name>
<can_delegate>1</can_delegate>
</capability>
</capabilities>
</credential>
</parent>
</credential>
<signatures>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" xml:id="Sig_Ref1">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#Ref1">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>jvLhG8xpXc+ABKP8KRMnHMWFi98=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>EZPbg858GFUvV/+b1RdfQfJc51ADq9r/Vov1ahEYcUXDrPjrNQQ4jTiHPWDMmwqX
kDDvwDHIkP8WlWF+Pk1NJNZRpmUFLtPdRG2DTWG/ySwp8UBJRLgkSno7N5ULmbxm
pA74Pi0YLOq2yLJpdm+HdDa1uqpI7YSgMSPoEUqTVX0=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIEAzCCA2ygAwIBAgIBADANBgkqhkiG9w0BAQQFADCBuDELMAkGA1UEBhMCVVMx
DTALBgNVBAgTBFV0YWgxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR0wGwYDVQQK
ExRVdGFoIE5ldHdvcmsgVGVzdGJlZDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0
aG9yaXR5MRgwFgYDVQQDEw9ib3NzLmVtdWxhYi5uZXQxKDAmBgkqhkiG9w0BCQEW
GXRlc3RiZWQtb3BzQGZsdXgudXRhaC5lZHUwHhcNMDUwMjAzMjIyOTU2WhcNMTAw
NzI3MjIyOTU2WjCBuDELMAkGA1UEBhMCVVMxDTALBgNVBAgTBFV0YWgxFzAVBgNV
BAcTDlNhbHQgTGFrZSBDaXR5MR0wGwYDVQQKExRVdGFoIE5ldHdvcmsgVGVzdGJl
ZDEeMBwGA1UECxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRgwFgYDVQQDEw9ib3Nz
LmVtdWxhYi5uZXQxKDAmBgkqhkiG9w0BCQEWGXRlc3RiZWQtb3BzQGZsdXgudXRh
aC5lZHUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMP7pPJRZQgRUmn+3G8N
fTdaIKEY3yQMnHKnh39F08xEdIu1GBZybssQjyNoabBpfICvA8cAVHvzaqumMnMw
7GUEKfeQ/yxcah4B4ClEUi1HyC9NPKekLjMbYdmvfucI8113bnYB1aVNh8mGkcUA
9xc3YWBUqtWLx9Tay4a4iZCVAgMBAAGjggEZMIIBFTAdBgNVHQ4EFgQU4f2YM843
s33w03Ux36fYMaD2mCAwgeUGA1UdIwSB3TCB2oAU4f2YM843s33w03Ux36fYMaD2
mCChgb6kgbswgbgxCzAJBgNVBAYTAlVTMQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQH
Ew5TYWx0IExha2UgQ2l0eTEdMBsGA1UEChMUVXRhaCBOZXR3b3JrIFRlc3RiZWQx
HjAcBgNVBAsTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEYMBYGA1UEAxMPYm9zcy5l
bXVsYWIubmV0MSgwJgYJKoZIhvcNAQkBFhl0ZXN0YmVkLW9wc0BmbHV4LnV0YWgu
ZWR1ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAg7cwFrcUW9uN
pvAv9BVbJA2IeyHNAj1URCIf3lAFSeOGWk0WGLJxO6QN0nm+K8O7DdtPXx6qPUdv
a/b6J+OtSE2lGXqQ4Nxczpjl8347M7EirbJA4mRJ+j06evbKKRHZ5dFfULb/T8sE
R9aYU3O/0/sCYeYySu+GedtfOk7zcaM=</X509Certificate>
<X509SubjectName>emailAddress=testbed-ops@flux.utah.edu,CN=boss.emulab.net,OU=Certificate Authority,O=Utah Network Testbed,L=Salt Lake City,ST=Utah,C=US</X509SubjectName>
<X509IssuerSerial>
<X509IssuerName>emailAddress=testbed-ops@flux.utah.edu,CN=boss.emulab.net,OU=Certificate Authority,O=Utah Network Testbed,L=Salt Lake City,ST=Utah,C=US</X509IssuerName>
<X509SerialNumber>0</X509SerialNumber>
</X509IssuerSerial>
</X509Data>
<KeyValue>
<RSAKeyValue>
<Modulus>
w/uk8lFlCBFSaf7cbw19N1ogoRjfJAyccqeHf0XTzER0i7UYFnJuyxCPI2hpsGl8
gK8DxwBUe/Nqq6YyczDsZQQp95D/LFxqHgHgKURSLUfIL008p6QuMxth2a9+5wjz
XXdudgHVpU2HyYaRxQD3FzdhYFSq1YvH1NrLhriJkJU=
</Modulus>
<Exponent>
AQAB
</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</signatures>
</signed-credential>
......@@ -52,13 +52,15 @@ my $SSLDIR = "$TB/lib/ssl";
my $EMULAB_CERT = "$TB/etc/emulab.pem";
my $EMULAB_KEY = "$TB/etc/emulab.key";
my $OPENSSL = "/usr/bin/openssl";
my $SAVEUID = $UID;
my $XMLLINT = "/usr/local/bin/xmllint";
my $XMLSEC1 = "/usr/local/bin/xmlsec1";
my $SCHEMA = "$TB/lib/protogeni/security/credential.xsd";
my $certfile;
my $keyfile;
my $deletefiles = 0;
my $certificate;
my $privkey;
my $signature = "";
my %credentials = ();
#
# We don't want to run this script unless its the real version.
......@@ -135,17 +137,96 @@ if (! defined($this_user)) {
}
#
# Must wrap the parser in eval since it exits on error.
# Verify that the credential conforms to the schema. The wrinkle is that it
# might already be a signed credential and we just need to add another
# signature to it, but either way it should still pass the schema check.
#
if (system("$XMLLINT -noout -schema $SCHEMA $xmlfile > /dev/null 2>&1")) {
fatal("$xmlfile does not conform to schema $SCHEMA");
}
#
# Bring in the credential file so we can mess with it.
#
my $parser = XML::LibXML->new;
$parser->validation(1);
my $doc = $parser->parse_file($xmlfile);
my $root = $doc->documentElement();
print Dumper($doc);
#
# Find the credential node, and then break up the hierarchy so that we
# can look at each part and then verify the chain of delegations.
#
my ($credentials_node) = $root->getElementsByTagName("credential");
my ($signatures_node) = $root->getElementsByTagName("signatures");
# openssl x509 -inform pem -in emulab.pem -pubkey -noout > publickey.pem
if (! (defined($credentials_node) && defined($signatures_node))) {
fatal("Malformed signed credentials input");
}
# Record the outermost credential in the array, indexed by name.
my ($xmlid_attribute) = $credentials_node->attributes();
my $xmlid = $xmlid_attribute->getValue();
$credentials{$xmlid} = { "node" => $credentials_node };
# Remember the leaf node, and the root which might change below.
my $leaf_xmlid = $xmlid;
my $leaf_cred = $credentials_node;
my $root_xmlid = $leaf_xmlid;
my $root_cred = $leaf_cred;
#
# The last child of the credentials node will be a parent credential,
# if there is a parent. Loop through finding each parent and place it
# in the credentials array. This is basically a doubly linked list of
# structures, each one pointing to its parent and child credentials.
#
my $temp = $credentials_node;
while (defined($temp)) {
my @childnodes = $temp->childNodes();
undef($temp);
foreach my $child (@childnodes) {
if (defined($child->localname) && $child->localname eq "parent") {
my ($parent_cred) = $child->getElementsByTagName("credential");
#print $parent_cred->toString() . "\n";
my ($xmlid_attribute) = $parent_cred->attributes();
my $parent_xmlid = $xmlid_attribute->getValue();
$credentials{$parent_xmlid} = { "node" => $parent_cred,
"child_xmlid" => $xmlid,
"child_cred" => $temp };
# Add this to the last credential info
$credentials{$xmlid}->{"parent_xmlid"} = $parent_xmlid;
$credentials{$xmlid}->{"parent_cred"} = $parent_cred;
$xmlid = $parent_xmlid;
$temp = $parent_cred;
# Remember this, might be root.
$root_xmlid = $xmlid;
$root_cred = $temp;
last;
}
}
}
#
# The certficate used to sign the credential is either the Emulab certificate
# or that of the user delegating the credential. For now lets just use the
# Emulab certificate. I will add user signing later.
#
$keyfile = $EMULAB_KEY;
$certfile = $EMULAB_CERT;
#
# Lets first make sure that the data has not been messed with; for each
# credential in the hierarchy check the signature. Remember, the signature
# covers the credential and all the parents up to the top.
#
foreach my $sigid (keys(%credentials)) {
system("$XMLSEC1 --verify --node-id Sig_$sigid ".
" --trusted-pem $certfile $xmlfile > /dev/null 2>&1")
== 0 or fatal("Credential $sigid does not verify");
}
exit(0);
sub cleanup()
......
#
# 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/xmlrpc
include $(OBJDIR)/Makeconf
# These scripts installed setuid, with sudo.
SETUID_BIN_SCRIPTS =
SETUID_SBIN_SCRIPTS =
SETUID_LIBX_SCRIPTS =
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: protogeni.py
include $(TESTBED_SRCDIR)/GNUmakerules
install: $(INSTALL_DIR)/protogeni/xmlrpc/protogeni.py
control-install:
clean:
rm -f *.o core
$(INSTALL_DIR)/protogeni/xmlrpc/%: %
@echo "Installing $<"
-mkdir -p $(INSTALL_DIR)/protogeni/xmlrpc
$(INSTALL) $< $@
#! /usr/bin/env python
#
# EMULAB-COPYRIGHT
# Copyright (c) 2008 University of Utah and the Flux Group.
# All rights reserved.
#
import sys
from xmlrpc import XmlRpcServer
class myexampleclass:
def method1 (self, meta, oneargument, anotherone):
print (meta, oneargument, anotherone)
return 0
def method2 (self, meta, *args):
sys.exit(0)
pass
pass
server = XmlRpcServer()
myinstance = myexampleclass()
server.register_class('myclass', myinstance)
sys.stdout.write("Content-type: text/xml\n\n")
server.execute()
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