aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--myrpki/Makefile39
l---------myrpki/POW1
-rw-r--r--myrpki/README660
-rw-r--r--myrpki/arin-rootcert.py69
-rw-r--r--myrpki/arin-to-csv.py119
-rw-r--r--myrpki/children-to-pubclients.py42
-rw-r--r--myrpki/examples/asns.csv8
-rw-r--r--myrpki/examples/children.csv9
-rw-r--r--myrpki/examples/myrpki.conf411
-rw-r--r--myrpki/examples/parents.csv8
-rw-r--r--myrpki/examples/prefixes.csv11
-rw-r--r--myrpki/examples/pubclients.csv10
-rw-r--r--myrpki/examples/roas.csv8
-rw-r--r--myrpki/examples/rsyncd.conf30
-rw-r--r--myrpki/myirbe.py512
-rw-r--r--myrpki/myrpki.py644
-rw-r--r--myrpki/rcynic.conf11
-rw-r--r--myrpki/ripe-to-csv.py133
l---------myrpki/rpki1
-rw-r--r--myrpki/schema.py199
-rw-r--r--myrpki/schema.rnc64
-rw-r--r--myrpki/schema.rng197
-rw-r--r--myrpki/setup-rootd.sh36
-rw-r--r--myrpki/setup-sql.py107
-rw-r--r--myrpki/sql-cleaner.py38
-rw-r--r--myrpki/sql-dumper.py35
-rw-r--r--myrpki/start-servers.py73
-rw-r--r--myrpki/test-all.sh43
-rwxr-xr-xmyrpki/verify-bpki.sh43
-rw-r--r--myrpki/xml-parse-test.py100
-rw-r--r--myrpki/yamltest.py702
31 files changed, 0 insertions, 4363 deletions
diff --git a/myrpki/Makefile b/myrpki/Makefile
deleted file mode 100644
index e828df71..00000000
--- a/myrpki/Makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-# $Id$
-
-all: schema.py
-
-lint: myrpki.xml schema.rng
- xmllint --noout --relaxng schema.rng myrpki.xml
-
-schema.rng: schema.rnc
- trang schema.rnc schema.rng
-
-schema.py: schema.rng
- echo >$@ 'import lxml.etree'
- echo >>$@ -n "myrpki = lxml.etree.RelaxNG(lxml.etree.fromstring('''"
- cat >>$@ schema.rng
- echo >>$@ "'''))"
-
-parse: myrpki.xml schema.py
- python xml-parse-test.py
-
-clean:
- rm -rf *.xml bpki.myrpki bpki.myirbe test screenlog.*
- python sql-cleaner.py
-
-format: myrpki.xml
- xmllint --format myrpki.xml
-
-graph:
- find . -name .svn -prune -o -type d -name 'bpki.*' -print | while read b; do python ../scripts/x509-dot.py $$b | dot -T ps2 | ps2pdf - $$b/graph.pdf; done
-
-verify:
- sh verify-bpki.sh
-
-backup:
- python sql-dumper.py
- tar cvvzf test.$$(TZ='' date +%Y.%m.%d.%H.%M.%S).tgz screenlog.* test backup.*.sql
- rm backup.*.sql
-
-test: schema.py
- python yamltest.py
diff --git a/myrpki/POW b/myrpki/POW
deleted file mode 120000
index 43fccd7b..00000000
--- a/myrpki/POW
+++ /dev/null
@@ -1 +0,0 @@
-../pow/buildlib/POW \ No newline at end of file
diff --git a/myrpki/README b/myrpki/README
deleted file mode 100644
index 3057fd0e..00000000
--- a/myrpki/README
+++ /dev/null
@@ -1,660 +0,0 @@
-$Id$
-
-INTRODUCTION
-
-The design of rpkid and friends assumes that certain tasks can be
-thrown over the wall to the registry's back end operation. This was a
-deliberate design decision to allow rpkid et al to remain independent
-of existing database schema, business PKIs, and so forth that a
-registry might already have. All very nice, but it leaves someone who
-just wants to test the tools or who has no existing back end with a
-fairly large programming project. The tools in this directory attempt
-to fill that gap.
-
-This is a basic implementation of what a registry back end would need
-to use rpkid and friends. These tools do not use every available
-option, nor are they necessarily as efficient as possible. Large
-registries will almost certainly want to roll their own tools, perhaps
-using these as a starting point. Nevertheless, we hope that these
-tools will at least provide a useful example.
-
-The primary tools here consist of two Python programs: myrpki.py and
-myirbe.py. The first is for use by any entity that needs resources
-allocated via the RPKI system, the second is for use by entities that
-actually run copies of rpkid and its several supporting programs.
-
-The basic idea here is that a user who has resources maintains a set
-of .csv files containing a text representation of the data needed by
-the back-end, along with a configuration file containing other
-parameters. The intent is that these be very simple files that are
-easy to generate either by hand or as a dump from relational database,
-spreadsheet, awk script, whatever works in your environment. Given
-these files, the user then runs the myrpki.py script to extract the
-relevant information and encode everything about its back end state
-into a single .xml file, which the script writes out to disk. The
-user then conveys this .xml file via some convenient means (PGP-signed
-mail, USB key, dog-sled) to the operator of the rpkid engine that will
-perform RPKI services on behalf of the user.
-
-The rpkid operator collects these .xml files from all the resource
-holders it hosts, and feeds them all into the myirbe.py script, which
-uses the data in the .xml files to populate the IRDB, create objects
-in rpkid and pubd via the left-right and publication protocols,
-etcetera. The script rewrites its input .xml files to contain any
-updated information (eg, PKCS #10 requests for business signing
-context certificates), so that the .xml file once again contains
-everything that must be communicated between the rpkid operator and
-hosted resource holder.
-
-The rpkid operator ships the updated .xml back to the user, who then
-runs the myrpki.py script again to perform any necessary actions (eg,
-issuing business signing context certificates given the PKCS #10
-request sent by myirbe.py), resulting in another update to the .xml
-file, which the user then ships back to the rpkid operator. This
-cycle repeats until nothing further needs to be changed.
-
-Note that, as certificates and CRLs have expiration and nextUpdate
-values, a low-level cycle of updates passing between resource holder
-and rpkid operator will be necessary as a part of steady state
-operation. [The current version of these tools does not yet
-regenerate these expiring objects, but fixing this will be a
-relatively minor matter.]
-
-Since we assume that anybody who bothers to run rpkid is also a
-resource holder, myirbe.py and myrpki.py can use the same
-configuration file, and myirbe.py will run myrpki.py automatically if
-the [myrpki] section of the configuration file is present.
-
-The third important file in this system is the configuration file for
-myrpki.py and myirbe.py. This contains a number of sections, some of
-which are for these scripts, others of which are for the OpenSSL
-command line tool, which these scripts use do most of the certificate
-work. The examples/ subdirectory contains a commented version of the
-configuration file that explains the various parameters.
-
-myrpki.py deliberately does not use any libraries other than the ones
-that ship with Python 2.5; in particular, it does not require any of
-the other Python RPKI code. This is intentional, to minimize
-portability issues for hosted resource holders. It does require a
-reasonably current version of the OpenSSL command line tool, but the
-version that is built as a side effect of building the rcynic relying
-party tool is adequate if the system copy of this tool isn't.
-
-The .csv files read by myrpki.py can be anything that the Python "csv"
-library understands. By default, they're in tab-delimited format
-(because the author finds this easier to read than the comma-delimited
-format), but this can be changed to fit local needs.
-
-Please note: tab-delimited CSV is a format defined by a certain
-popular spreadsheet program, and is *not* the same as
-whitespace-separated text. Tab characters are *punctuation*, and each
-tab character indicates the division between two columns. Two tab
-characters in a row indicates a separator, a blank cell, and another
-separator, not one separator. The upshot of all this is that
-attempting to make your columns line up prettily will not work as you
-expect, you will end up with too many cells, some of them empty.
-
-A number of the fields in the configuration or CSV files involve
-certificates. Some of these are built automatically, others must be
-imported so that the scripts can cross-certify them. The certificates
-you need to import are all self-signed BPKI trust anchor certificates
-generated by other entities; you import them by specifying the name of
-a file where you stored the BPKI certificate in question (in OpenSSL
-"PEM" format).
-
-Keep reading, and don't panic.
-
-The default configuration file name is myrpki.conf.
-
-See examples/myrpki.conf for details on the variables that you can
-(and in some cases must) set.
-
-See examples/*.csv for commented examples of the several CSV files.
-Note that the comments themselves are not legal CSV, they're just
-present to make it easier to understand the examples.
-
-GETTING STARTED -- OVERVIEW
-
-As explained above, the two basic programs are myrpki.py (for resource
-holders) and myirbe.py (for rpkid operators); myirbe.py runs myrpki.py
-automatically for a rpkid operator's own resources if myirbe.py finds
-a [myrpki] section in its configuration file.
-
-Which process you need to follow to get started depends on whether you
-are running rpkid yourself or will be hosted by somebody else. We
-call the first case "self-hosted", because the software treats running
-rpkid to handle resources that you yourself hold as if you are an rpkid
-operator who is hosting an entity that happens to be yourself.
-
-"$top" in the following refers to wherever you put the
-subvert-rpki.hactrn.net code. Once we have autoconf and "make
-install" targets, this will be some system directory or another; for
-now, it's wherever you checked out a copy of the code from the
-subversion repository or unpacked a tarball of the code.
-
-GETTING STARTED -- HOSTED CASE
-
-The basic steps involved in getting started for a resource holder who
-is being hosted by somebody else are:
-
-1) Obtain contact information and BPKI trust anchors from RPKI parents
- and an RPKI publication service (see below for details).
-
-2) Write a configuration file (copy $top/myrpki/examples/myrpki.conf
- and edit as needed). You can skip the sections associated with the
- various daemons and their runtime control tools ([myirbe], [rpkid],
- [irdbd], [pubd], [rootd], [irbe_cli]). You *do* need to configure
- the [myrpki] section.
-
-3) Using $top/myrpki/examples/*.csv as a guide, create a set of CSV
- files representing RPKI parents, RPKI children, resources to be
- assigned to RPKI children, and ROAs to be generated once the
- necessary RPKI certificates are available. Most of these CSV files
- can be empty while first getting started, the only file that
- absolutely must be populated is the file describing parents.
-
- You may choose to place your configuration file (which we will
- refer to here as myrpki.conf) and your CSV files in their own
- directory. The software doesn't really care. If you use absolute
- names for all the filename entries in the configuration file and
- CSV files, you can put the files wherever you like; if you use
- relative names, they will be interpreted relative to the directory
- in which you run the program that reads the file.
-
- [At some future date we may provide a default directory for
- relative filenames such as /usr/local/etc/rpki, but the above
- description holds for now.]
-
-4) Run myrpki.py to generate a BPKI trust anchor and collect all the
- data from the configuration file, CSV files, and newly created BPKI
- into a single XML file which can be shipped to the rpkid operator
- who is hosting your resources.
-
-5) Send the XML file generated in step (4) to your rpkid operator.
-
-6) Wait for your rpkid operator to ship you back an updated XML file
- containing a PKCS #10 certificate request for the BPKI signing
- context (BSC) created by rpkid.
-
-7) Run myrpki.py again with the XML file received in step (6), to
- issue the BSC certificate and update the XML file again to contain
- the newly issued BSC certificate.
-
-8) Send the updated XML file back to your rpkid operator.
-
-At this point you're done with initial setup. You will need to run
-myrpki.py again whenever you make any changes to your configuration
-file or CSV files. [Once myrpki.py knows how to update BPKI CRLs, you
-will also need to run myrpki.py periodically to keep your BPKI CRLs up
-to date.] Any time you run myrpki.py, you should send the updated XML
-file to your rpkid operator, who will [generally?] send you a further
-updated XML file in response.
-
-GETTING STARTED -- SELF-HOSTED CASE
-
-The first few steps involved in getting started for a self-hosted
-resource holder (that is, a resource holder that runs its own copy of
-rpkid) are the same as in the hosted case above; after that the
-process diverges.
-
-[As of the time at which these instructions were written, it had
-become clear that there really should be an additional setup script
-which automates much of the following. That script hasn't been
-written yet, so for the moment this documents the setup process as it
-stands now. Once that setup script has been written, these
-instructions will be updated to match. In the meantime, please accept
-the author's apologies for the tedious nature of the current setup
-process.]
-
-The [current] steps are:
-
-1) Obtain contact information and BPKI trust anchors from RPKI parents
- and an RPKI publication service (see below for details).
-
-2) Write a configuration file (copy examples/myrpki.conf and edit as
- needed). You need to configure the [myrpki] and [myirbe] sections
- as well as the sections associated with the daemons you will be
- running ([rpkid], [irdbd], [irbe_cli]). You only need to configure
- the [pubd] section if you intend to run your own publication
- service: in general this is not recommended, because each
- additional publication service in the RPKI universe places a small
- additional burden on every relying party, since every relying party
- has to download data from every publication service. In general
- it's better to use an existing publication service operated by
- somebody else (eg, your RPKI parent) if you can. In general most
- cases you can leave the [rootd] section alone, as in most cases you
- should not be running rootd.
-
-3) Using $top/myrpki/examples/*.csv as a guide, create a set of CSV
- files representing RPKI parents, RPKI children, resources to be
- assigned to RPKI children, and ROAs to be generated once the
- necessary RPKI certificates are available. Most of these CSV files
- can be empty while first getting started, the only file that
- absolutely must be populated is the file describing parents.
-
- You may choose to place your configuration file (which we will
- refer to here as myrpki.conf) and your CSV files in their own
- directory. The software doesn't really care. If you use absolute
- names for all the filename entries in the configuration file and
- CSV files, you can put the files wherever you like; if you use
- relative names, they will be interpreted relative to the directory
- in which you run the program that reads the file.
-
- [At some future date we may provide a default directory for
- relative filenames such as /usr/local/etc/rpki, but the above
- description holds for now.]
-
-4) See rpkid/doc/Installation, and follow the basic installation
- instructions there to build the RFC-3779-aware OpenSSL code and
- associated Python extension module.
-
-5) Next, you need to set up the MySQL databases that rpkid et al will
- use. The MySQL database, username, and password values all need to
- match the ones you specified in myrpki.conf. There are two
- different ways you can do this:
-
- a) You can use the setup-sql.py script, which prompts you for your
- MySQL root password then attempts to do everything else
- automatically using values from myrpki.conf; or
-
- b) You can do it manually.
-
- The first approach is simple:
-
- $ python setup-sql.py
- Please enter your MySQL root password:
-
- The script should tell you what databases it creates. You can use
- the -v option if you want to see more details about what it's doing.
-
- If you'd prefer to do the SQL setup manually, perhaps because you
- have valuable data in other MySQL databases and you don't want to
- trust some random setup script with your MySQL root password,
- you'll need to use the MySQL command line tool, as follows:
-
- $ mysql -u root -p
-
- mysql> CREATE DATABASE irdb_database;
- mysql> GRANT all ON irdb_database.* TO irdb_user@localhost IDENTIFIED BY 'irdb_password';
- mysql> USE irdb_database;
- mysql> SOURCE $top/rpkid/irdbd.sql;
- mysql> CREATE DATABASE rpki_database;
- mysql> GRANT all ON rpki_database.* TO rpki_user@localhost IDENTIFIED BY 'rpki_password';
- mysql> USE rpki_database;
- mysql> SOURCE $top/rpkid/rpkid.sql;
- mysql> COMMIT;
- mysql> quit
-
- where "irdb_database", "irdb_user", "irdb_password",
- "rpki_database", "rpki_user", and "rpki_password" are the
- appropriate values from your configuration file.
-
- If you are running pubd and doing manual SQL setup, you'll also
- have to do:
-
- $ mysql -u root -p
- mysql> CREATE DATABASE pubd_database;
- mysql> GRANT all ON pubd_database.* TO pubd_user@localhost IDENTIFIED BY 'pubd_password';
- mysql> USE pubd_database;
- mysql> SOURCE $top/rpkid/pubd.sql;
- mysql> COMMIT;
- mysql> quit
-
-6) Run myirbe.py -b to set up the initial BPKI structure needed to run
- your daemons:
-
- $ python $top/myrpki/myirbe.py -b
-
- The -b option tells myrpki.py that you want it to stop after the
- initial BPKI setup, regardless of whether it thinks this is
- necessary. If you have not done this before it should tell you
- that it has updated the BPKI and that you need to (re)start daemons
- now.
-
-7) If you are running your own publication repository (that is, if you
- are running pubd), you will also need to set up an rsyncd server or
- configure your existing one to serve pubd's output. There's a
- sample configuration file in $top/myrpki/examples/rsyncd.conf, but
- you may need to do something more complicated if you are already
- running rsyncd for other purposes. See the rsync(1) and
- rsyncd.conf(5) manual pages for more details.
-
-8) Start the daemons. You can use $top/myrpki/start-servers.py to do
- this, or write your own script.
-
- If you intend to run pubd, you should make sure that the directory
- you specified as publication-base in the [pubd] section exists and
- is writable by the userid that will be running pubd, and should
- also make sure to start rsyncd.
-
-9) Run myirbe.py again, twice, this time with no arguments.
-
- $ python $top/myrpki/myirbe.py
- $ python $top/myrpki/myirbe.py
-
- The reason for running myirbe.py twice at this point is explained
- in the Introduction section, above; in brief, the first run sets up
- almost everything, but a second pass is required to generate the
- BSC certificate.
-
-At this point, if everything went well, rpkid should be up,
-configured, and starting to obtain resource certificates from its
-parents, generate CRLs and manifests, and so forth. At this point you
-should go figure out how to use the relying party tool, rcynic: see
-$top/rcynic/README if you haven't already done so.
-
-If and when you change your CSV files, you should run myirbe.py again
-to feed the changes into the daemons.
-
-GETTING STARTED -- HOSTING CASE
-
-If you are running rpkid not just for your own resources but also to
-host other resource holders (see "HOSTED CASE" above), your setup will
-be almost the same as in the self-hosted case (see "SELF-HOSTED CASE",
-above), with one procedural change: you will need to tell myirbe.py to
-process the XML files produced by the resource holders you are
-hosting. You do this by specifying the names of all those XML files
-on myirbe's command line. So, if you are hosting two friends, Alice
-and Bob, then, everywhere the instructions for the self-hosted case
-say to run myirbe.py with no arguments, you will instead run it with
-the names of Alice's and Bob's XML files:
-
- $ python $top/myrpki/myirbe.py alice.xml bob.xml
-
-Note that myirbe.py sometimes modifies these XML files, in which case
-it will write them back to the same filenames. While it is possible
-to figure out the set of circumstances in which myirbe.py will modify
-XML files (at present, this only happens when myirbe.py has to ask
-rpkid to create a new BSC keypair and PKCS #10 certificate request),
-it may be easiest just to ship back an updated copy of the XML file
-after every you run myirbe.py.
-
-GETTING STARTED -- "PURE" HOSTING CASE
-
-In general we assume that anybody who bothers to run rpkid is also a
-resource holder, but the software does not insist on this. If you are
-running rpkid solely for others and have no resources of your own, the
-process is almost identical to the "HOSTING CASE", above. The one
-change is that you should *not* have a [myrpki] section in your
-configuration file.
-
-A (perhaps) slightly-more-plausible use for this capability would be
-if you are an rpkid-running resource holder who wants for some reason
-to keep the resource-holding side of your operation completely
-separate from the rpkid-running side of your operation. This is
-essentially the pure-hosting model, just with an internal hosted
-entity within a different part of your own organization.
-
-DATA YOU NEED FROM YOUR RPKI PARENT AND PUBLICATION SERVICE
-
-In order to connect to your RPKI parent, you will need to supply your
-BPKI trust anchor to your parent and obtain four pieces of data from
-your parent.
-
-Assuming that you are using something resembling the default
-configuration, your BPKI trust anchor will be bpki.myrpki/ca.cer.
-This is an OpenSSL "PEM" format file. You will need to provide this
-to your RPKI parent.
-
-The data you need from your parent are:
-
-- The service URL for your entry point into your parent's rpkid.
- Typically this will be a URL of the form:
-
- https://example.org:port/up-down/parenthandle/myhandle
-
- where "example.org" and "port" are the DNS name and TCP port of your
- parent's rpkid service, "parenthandle" is your parent's name
- (handle) for itself, and "myhandle" is your parent's name (handle)
- for you;
-
-- Your parent's BPKI trust anchor for its resource-holding persona
- (the entity represented by "parenthandle", above);
-
-- Your parent's BPKI trust anchor for daemons it operates; and
-
-- The handle by which your parent refers to you in its database,
- generally the same as "myhandle" in the service URL.
-
-The need for two separate BPKI trust anchors for your parent is due to
-a limitation of the HTTPS protocol; recent extensions to TLS provide a
-way to work around this limitation, but at this point in time rpkid
-can't assume support for the TLS extension in question. Roughly
-speaking, the first BPKI trust anchor corresponds to the your parent
-as a resource-holding entity, while the second corresponds to your
-parent as an rpkid-operating entity.
-
-These four data correspond, in order, to the second, third, fourth,
-and fifth columns in your parents.csv file. In most cases you will
-have only one parent, so there will be only one line in that file.
-
-The first field in the parents.csv file is your name for your parent,
-which can be any name you like so long as it doesn't conflict with
-your name for another parent.
-
-The sixth field in the parents.csv file determines the base rsync URI
-for objects signed by certificates issued by this parent. If you are
-using an external publication service (recommended), your parent must
-supply this URI as well; a typical value would be
-rsync://example.org/Dad/Me/ or rsync://example.org/Grandma/Dad/Me/.
-
-If you are running your own copy of pubd, this URI should point to the
-directory that corresponds to the publication-base setting in the
-[pubd] section of your configuration file.
-
-If you are using an external publication service (which might be your
-parent, grandparent, or any ancestor all the way up to the root), your
-publication service will also need to tell you:
-
-- The service URL for the publication service (pubd_base parameter in
- [myirbe] section of your configuration file);
-
-- The publication service's name for you (repository_handle field in
- [myrpki] section of your configuration file); and
-
-- The BPKI trust anchor for the publication service
- (repository_bpki_certificate field in [myrpki] section of your
- configuration file).
-
-Note that the first of these three parameters only applies if you are
-running rpkid, while the second and third apply even if your resources
-are hosted on somebody else's rpkid. In effect, this means that all
-the entities sharing a single rpkid must also share a single
-publication service. This is a restriction of the myrpki/myirbe
-software, not rpkid itself, so it could be removed if there were a
-strong need to do so, but given that each additional publication
-service imposes a small additional burden on every relying party in
-the world, we do not view this restriction as a problem.
-
-DATA YOU NEED TO GIVE YOUR RPKI CHILDREN AND USERS OF YOUR PUBLICATION SERVICE
-
-First, read the previous section describing what children and
-publication clients expect to receive.
-
-- The service URL for your rpkid will be an HTTPS URL of the form
-
- https://example.org:port/up-down/yourhandle/childhandle
-
- where "example.org" and "port" are the DNS name and TCP port of your
- rpkid service ([rpkid] section of your configuration file),
- "yourhandle" is the handle parameter from the [myrpki] section of
- your configuration file, and "childhandle" is this child's handle as
- it appears in the first columns of your children.csv, asns.csv, and
- prefixes.csv files;
-
-- The BPKI trust anchor for your resource-holding persona is your
- bpki.myrpki/ca.cer;
-
-- The BPKI trust anchor for daemons you operate is your
- bpki.myirbe/ca.cer; and
-
-- The handle by which you refer to your child is the same as
- "childhandle", above.
-
-If you are operating a publication service, you will also need to
-supply:
-
-- Your pubd service URL, which will be an HTTPS URL of the form
-
- https://example.org:port/
-
- where "example.org" and "port" are the server-host and server-port
- parameters from the [pubd] section of your configuration file;
-
-- Your name for this publication client, which is the first column of
- your pubclients.csv file (note that this can be a structured name
- using "/" characters as a hierarchy delimiter); and
-
-- The BPKI trust anchor for the daemons you operate
- (bpki.myirbe/ca.cer).
-
-Note that, if you are operating pubd, it's best for relying parties if
-your children's publication points are underneath yours within the
-publication hierarchy, to allow rsync to check for updates as
-efficiently as possible. pubd's support for hierarchical client
-handles is intended to simplify this: if you have a child Alice, who
-has children Bob and Bill, and you, your children, and your
-grandchildren will all be using your publication service, you might
-assign <client_handle> and <sia_base> parameters (first and third
-fields in pubclients.csv) as follows:
-
-Me rsync://rpki.example.org/Me/
-Me/Alice rsync://rpki.example.org/Me/Alice/
-Me/Alice/Bob rsync://rpki.example.org/Me/Alice/Bob/
-Me/Alice/Bill rsync://rpki.example.org/Me/Alice/Bill/
-
-Note that you will need trust anchors for your children and any
-publication clients. In both cases the trust anchor you need is the
-child's or client's resource-holding BPKI trust anchor
-(bpki.myrpki/ca.cer); who operates the rpkid that host your children
-or publication clients is not strictly relevant to the authorization
-model, what matters is who holds the resources and is authorized to
-request and publish RPKI data derived from them.
-
-TROUBLESHOOTING
-
-If you run into trouble setting up this package, the first thing to do
-is categorize the kind of trouble you are having. If you've gotten
-far enough to be running the daemons, check their log files. If
-you're seeing Python exceptions, read the error messages. If you're
-getting TLS errors, check to make sure that you're using all the right
-BPKI certificates and service contact URLs.
-
-TLS configuration errors are, unfortunately, notoriously difficult to
-debug, because connections due to misconfiguration usually fail early,
-deep in the guts of the OpenSSL TLS code, where there isn't enough
-application context available to provide useful error messages.
-
-If you've completed the steps above, everything appears to have gone
-OK, but nothing seems to be happening, the first thing to do is check
-the logs to confirm that nothing is actively broken. rpkid's log
-should include messages telling you when it starts and finishes its
-internal "cron" cycle. It can take several cron cycles for resources
-to work their way down from your parent into a full set of
-certificates and ROAs, so have a little patience. rpkid's log should
-also include messages showing every time it contacts its parent(s) or
-attempts to publish anything.
-
-rcynic in fully verbose mode provides a fairly detailed explanation of
-what it's doing and why objects that fail have failed.
-
-You can use rsync (sic) to examine the contents of a publication
-repository one directory at a time, without attempting validation, by
-running rsync with just the URI of the directory on its command line:
-
- $ rsync rsync://rpki.example.org/where/ever/
-
-[Maybe there should be something here explaining how to use
-irbe_cli.py for debugging, but the syntax is fairly obscure as it's
-just a command line interface to the left-right and publication
-protocols -- almost certainly want a friendlier tool for
-troubleshooting.]
-
-KNOWN ISSUES
-
-The lxml package provides a Python interface to the Gnome libxml2 and
-libxslt C libraries. This code has been quite stable for several
-years, but initial testing with lxml compiled and linked against a
-newer version of libxml2 ran into problems (specifically, gratuitous
-RelaxNG schema validation failures). libxml2 2.7.3 worked; libxml2
-2.7.5 did not work on the test machine in question. Reverting to
-libxml2 2.7.3 fixed the problem. Rewriting the two lines of Python
-code that were triggering the lxml bug appears to have solved the
-problem, so the code now works properly with libxml 2.7.5, but if you
-start seeing weird XML validation failures, it might be another
-variation of this lxml bug.
-
-An earlier version of this code ran into problems with what appears to
-be an implementation restriction in the the GNU linker ("ld") on
-64-bit hardware, resulting in obscure build failures. The workaround
-for this required use of shared libraries and is somewhat less
-portable than the original code, but without it the code simply would
-not build in 64-bit environments with the GNU tools. The current
-workaround appears to behave properly, but the workaround requires
-that the pathname to the RFC-3779-aware OpenSSL shared libraries be
-built into the _POW.so Python extension module. At the moment, in the
-absence of "make install" targets for the Python code and libraries,
-this means the build directory; eventually, once we're using autoconf
-and installation targets, this will be the installation directory. If
-necessary, you can override this by setting the LD_LIBRARY_PATH
-environment variable, see the ld.so man page for details. This is a
-relatively minor variation on the usual build issues for shared
-libraries, it's just annoying because shared libraries should not be
-needed here and would not be if not for this GNU linker issue.
-
-
-
-Sketch towards a simple description of the BPKI (sic).
-
-This started out as notes to myself during a redesign, and badly needs
-rewriting.
-
-Hosted (myrpki) entity needs:
-
-- Self-signed BPKI root (doesn't really need to be self-signed, nobody
- else will care, but self-signed is simplest for our purposes). This
- is what we've been calling the "self" cert in testbed.py.
-
-- BSC EE issued by self-signed root.
-
-- Cross-certs of every foreign entity (parent, child, or pubd): these
- are CA certs with pathLenConstraint 0. Input for this cross-cert is
- self-signed (or whatever) from foreign entity, output is
- pathLenConstraint 0 CA cert issued by myrpki entity's own
- self-signed root.
-
-Hosting rpkid (myirbe) needs:
-
-- Self-signed BPKI root
-
-- BSC EE certs for rpkid, irdbd, irbe_cli, etc
-
-- For each hosted entity (including self-hosting):
-
- Cross-cert of hosted entity's root, issued by rpkid root: CA cert
- with pathLenConstraint 1
-
- In theory that's all that's required, everything else is handled
- through the hosted entity's cert chain.
-
-pubd needs:
-
-- Self signed root (might share with rpkid but let's keep it separate
- conceptually)
-
-- BSC EE certs for pubd and irbe_cli
-
-- For each client entity of pubd:
-
- Cross-cert of client entity's self cert (pathLenConstraint 0).
-
- This should allow pubd to verify clients' BSC EE certs without
- getting into transitive CA relationships.
-
-rootd (when applicable at all) needs:
-
-- Self-signed root
-
-- BSC EE cert for talking up-down (server) with one and only child
-
-- Cross-cert (pathLenConstraint 0) of one and only child's self cert.
diff --git a/myrpki/arin-rootcert.py b/myrpki/arin-rootcert.py
deleted file mode 100644
index 09180af6..00000000
--- a/myrpki/arin-rootcert.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""
-Generate config for a test RPKI root certificate for resources
-specified in asns.csv and prefixes.csv.
-
-This script is separate from arin-to-csv.py so that we can convert on
-the fly rather than having to pull the entire database into memory.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import csv, myrpki, sys
-
-holder = "arin"
-
-if len(sys.argv) == 2:
- holder = sys.argv[1]
-elif len(sys.argv) > 1:
- raise RuntimeError, "Usage: %s [holder]" % sys.argv[0]
-
-print '''\
-[req]
-default_bits = 2048
-default_md = sha256
-distinguished_name = req_dn
-prompt = no
-encrypt_key = no
-
-[req_dn]
-CN = Pseudo-%(HOLDER)s testbed root RPKI certificate
-
-[x509v3_extensions]
-basicConstraints = critical,CA:true
-subjectKeyIdentifier = hash
-keyUsage = critical,keyCertSign,cRLSign
-subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:rsync://%(holder)s.rpki.net/%(holder)s/,1.3.6.1.5.5.7.48.10;URI:rsync://%(holder)s.rpki.net/%(holder)s/root.mnf
-certificatePolicies = critical,1.3.6.1.5.5.7.14.2
-sbgp-autonomousSysNum = critical,@rfc3779_asns
-sbgp-ipAddrBlock = critical,@rfc3997_addrs
-
-[rfc3779_asns]
-''' % { "holder" : holder.lower(),
- "HOLDER" : holder.upper() }
-
-for i, asn in enumerate(asn for handle, asn in myrpki.csv_open("asns.csv")):
- print "AS.%d = %s" % (i, asn)
-
-print '''\
-
-[rfc3997_addrs]
-
-'''
-
-for i, prefix in enumerate(prefix for handle, prefix in myrpki.csv_open("prefixes.csv")):
- v = 6 if ":" in prefix else 4
- print "IPv%d.%d = %s" % (v, i, prefix)
diff --git a/myrpki/arin-to-csv.py b/myrpki/arin-to-csv.py
deleted file mode 100644
index fc98bb64..00000000
--- a/myrpki/arin-to-csv.py
+++ /dev/null
@@ -1,119 +0,0 @@
-"""
-Parse a WHOIS research dump and write out (just) the RPKI-relevant
-fields in myrpki-format CSV syntax.
-
-NB: The input data for this script comes from ARIN under an agreement
-that allows research use but forbids redistribution, so if you think
-you need a copy of the data, please talk to ARIN about it, not us.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import gzip, csv, myrpki
-
-class Handle(object):
-
- want_tags = ()
-
- debug = False
-
- def set(self, tag, val):
- if tag in self.want_tags:
- setattr(self, tag, "".join(val.split(" ")))
-
- def check(self):
- for tag in self.want_tags:
- if not hasattr(self, tag):
- return False
- if self.debug:
- print repr(self)
- return True
-
-class ASHandle(Handle):
-
- want_tags = ("ASHandle", "ASNumber", "OrgID")
-
- def __repr__(self):
- return "<%s %s.%s %s>" % (self.__class__.__name__,
- self.OrgID, self.ASHandle, self.ASNumber)
-
- def finish(self, ctx):
- if self.check():
- ctx.asns.writerow((self.OrgID, self.ASNumber))
-
-class NetHandle(Handle):
-
- NetType = None
-
- want_tags = ("NetHandle", "NetRange", "NetType", "OrgID")
-
- def finish(self, ctx):
- if self.NetType in ("allocation", "assignment") and self.check():
- ctx.prefixes.writerow((self.OrgID, self.NetRange))
-
- def __repr__(self):
- return "<%s %s.%s %s %s>" % (self.__class__.__name__,
- self.OrgID, self.NetHandle,
- self.NetType, self.NetRange)
-
-class V6NetHandle(NetHandle):
-
- want_tags = ("V6NetHandle", "NetRange", "NetType", "OrgID")
-
- def __repr__(self):
- return "<%s %s.%s %s %s>" % (self.__class__.__name__,
- self.OrgID, self.V6NetHandle,
- self.NetType, self.NetRange)
-
-class main(object):
-
- types = {
- "ASHandle" : ASHandle,
- "NetHandle" : NetHandle,
- "V6NetHandle" : V6NetHandle }
-
- @staticmethod
- def parseline(line):
- tag, sep, val = line.partition(":")
- assert sep, "Couldn't find separator in %r" % line
- return tag.strip(), val.strip()
-
- @staticmethod
- def csvout(fn):
- return csv.writer(open(fn, "w"), dialect = myrpki.csv_dialect)
-
- def __init__(self):
- self.asns = self.csvout("asns.csv")
- self.prefixes = self.csvout("prefixes.csv")
- f = gzip.open("arin_db.txt.gz")
- cur = None
- for line in f:
- line = line.expandtabs().strip()
- if not line:
- if cur:
- cur.finish(self)
- cur = None
- elif not line.startswith("#"):
- tag, val = self.parseline(line)
- if cur is None:
- cur = self.types[tag]() if tag in self.types else False
- if cur:
- cur.set(tag, val)
- if cur:
- cur.finish(self)
-
-main()
diff --git a/myrpki/children-to-pubclients.py b/myrpki/children-to-pubclients.py
deleted file mode 100644
index 025d3d42..00000000
--- a/myrpki/children-to-pubclients.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""
-Convert children.csv to (initial) pubclients.csv. You may wish to
-play sort/join/etc games with the output of this to avoid overwriting
-other publication clients you've configured.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import sys, csv, myrpki, getopt, time, os, rpki.config
-
-os.environ["TZ"] = "UTC"
-time.tzset()
-
-cfg_file = "myrpki.conf"
-
-opts, argv = getopt.getopt(sys.argv[1:], "c:h?", ["config=", "help"])
-for o, a in opts:
- if o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
- if o in ("-c", "--config"):
- cfg_file = a
-
-base = rpki.config.parser(cfg_file, "myirbe").get("rsync_base")
-
-csv.writer(sys.stdout, dialect = myrpki.csv_dialect).writerows(
- (handle, cert, "%s/children/%s/" % (base.rstrip("/"), handle))
- for handle, expiration, cert in myrpki.csv_open("children.csv"))
diff --git a/myrpki/examples/asns.csv b/myrpki/examples/asns.csv
deleted file mode 100644
index 804cf839..00000000
--- a/myrpki/examples/asns.csv
+++ /dev/null
@@ -1,8 +0,0 @@
-# $Id$
-#
-# Syntax: <child_handle> <asn>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-Alice 64533
diff --git a/myrpki/examples/children.csv b/myrpki/examples/children.csv
deleted file mode 100644
index da29e8b5..00000000
--- a/myrpki/examples/children.csv
+++ /dev/null
@@ -1,9 +0,0 @@
-# $Id$
-#
-# Syntax: <child_handle> <validitydate> <bpki_cert_filename>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-Alice 2009-07-27T08:24:53Z Alice.ta.cer
-Bob 2009-07-27T08:24:53Z Bob.ta.cer
diff --git a/myrpki/examples/myrpki.conf b/myrpki/examples/myrpki.conf
deleted file mode 100644
index 0eded59b..00000000
--- a/myrpki/examples/myrpki.conf
+++ /dev/null
@@ -1,411 +0,0 @@
-# $Id: myrpki.conf 2722 2009-08-31 22:24:48Z sra $
-#
-# Config file for myrpki.py, myirbe.py, and RPKI daemons when used
-# with myrpki.py etc. Notes:
-#
-# - There's some duplication of settings between some of the sections,
-# because each of the several daemons and control programs was
-# written as a free-standing program. Lumping all of the config for
-# all of them into a single config file is just a convenience for
-# simple configurations; in complex cases you might not have any two
-# of them running on the same machine.
-#
-# - This config file is also read by the OpenSSL command line tool
-# running under mypki.py, so syntax must remain compatable with both
-# OpenSSL and Python config file parsers, and there's a big chunk of
-# OpenSSL voodoo towards the end of this file.
-
-################################################################
-
-[myrpki]
-
-# Handle naming hosted resource-holding entity (<self/>) represented
-# by this myrpki instance. Syntax is an identifier (ASCII letters,
-# digits, hyphen, underscore -- no whitespace, non-ASCII characters,
-# or other punctuation). You need to set this.
-
-handle = Me
-
-# BPKI trust anchor for the repository in which this <self/> will be
-# publishing its outputs. You need to set this.
-
-repository_bpki_certificate = repository-ta.cer
-
-# Name by which repository will know this <self/>. This may be a
-# structured handle, eg, "Grandma/Mom/Me" or might be a simple handle,
-# depending on how the repository is set up. Syntax is same as
-# "handle", with the addition of "/" characters as an allowed
-# delimiter. You need to set this.
-
-repository_handle = Me
-
-# Names of various input and output files. Don't change these without
-# a good reason.
-
-roa_csv = roas.csv
-children_csv = children.csv
-parents_csv = parents.csv
-prefix_csv = prefixes.csv
-asn_csv = asns.csv
-xml_filename = myrpki.xml
-bpki_directory = bpki.myrpki
-
-#################################################################
-
-[myirbe]
-
-# Base of service URL for pubd. myirbe.py uses this value to
-# configure <repository/> objects in rpkid. If you are running your
-# own copy of pubd (see "want_pubd"), myirbe.py also uses this to
-# contact your copy of pubd in order to configure it.
-#
-# You need to configure this.
-
-pubd_base = https://pubd.example.org:4402/
-
-# Base of service URL for rpkid. myirbe.py uses this to contact your
-# rpkid so it can configure it.
-#
-# You need to configure this.
-
-rpkid_base = https://rpkid.example.org:4404
-
-# Whether you want myirbe.py to attempt to configure your own copy of
-# pubd. In general, it's best to use your parent's pubd if you can,
-# to reduce the overall number of publication sites that relying
-# parties need to check, so don't enable this unless you have a good
-# reason. See the [pubd] section if you do enable this.
-#
-# Enabling this when you are -not- running your own copy of pubd will
-# cause myirbe.py to fail when it attempts to perform runtime
-# configuration of your nonexistant pubd.
-
-want_pubd = false
-
-# Whether you want myirbe.py to generate BPKI certs for running your
-# very own copy of rootd. Don't enable this unless you really know
-# what you're doing. See [rootd] section below for further comments.
-
-want_rootd = false
-
-# Where to put BPKI stuff for the IRBE operator (entity that operates
-# rpkid etc). Don't change this without a reason.
-
-bpki_directory = bpki.myirbe
-
-#################################################################
-
-[rpkid]
-
-# MySQL database name, user name, and password for rpkid to use to
-# store its data. You need to configure these.
-
-sql-database = rpki
-sql-username = rpki
-sql-password = fnord
-
-# Host and port on which rpkid should listen for HTTPS service
-# requests. These should match rpkid_base in the [myirbe] section.
-# You need to configure these.
-
-server-host = rpkid.example.org
-server-port = 4404
-
-# HTTPS service URL rpkid should use to contact irdbd. If irdbd is
-# running on the same machine as rpkid, this can and probably should
-# be a loopback URL, since nobody but rpkid needs to talk to irdbd.
-
-irdb-url = https://localhost:4403/
-
-# Where rpkid should look for BPKI certs and keys used in the
-# left-right protocol. The following values match where myirbe.py
-# will have placed things. Don't change these without a reason.
-
-bpki-ta = bpki.myirbe/ca.cer
-rpkid-key = bpki.myirbe/rpkid.key
-rpkid-cert = bpki.myirbe/rpkid.cer
-irdb-cert = bpki.myirbe/irdbd.cer
-irbe-cert = bpki.myirbe/irbe.cer
-
-#################################################################
-
-[irdbd]
-
-# MySQL database name, user name, and password for irdbd to use to
-# store its data. You need to configure these.
-
-sql-database = irdb
-sql-username = irdb
-sql-password = fnord
-
-# HTTP service URL irdbd should listen on. This should match the
-# irdb-url parameter in the [rpkid] section; see comments there.
-
-https-url = https://localhost:4403/
-
-# Where irdbd should look for BPKI certs and keys used in the
-# left-right protocol. The following values match where myirbe.py
-# will have placed things. Don't change these without a reason.
-
-bpki-ta = bpki.myirbe/ca.cer
-rpkid-cert = bpki.myirbe/rpkid.cer
-irdbd-cert = bpki.myirbe/irdbd.cer
-irdbd-key = bpki.myirbe/irdbd.key
-
-#################################################################
-
-[pubd]
-
-# MySQL database name, user name, and password for pubd to use to
-# store (some of) its data. You need to configure these.
-
-sql-database = pubd
-sql-username = pubd
-sql-password = fnord
-
-# Root of directory tree where pubd should write out published data.
-# You need to configure this, and the configuration should match up
-# with the directory where you point rsyncd. Neither pubd nor rsyncd
-# much cares -where- you tell them to put this stuff, the important
-# thing is that the rsync:// URIs in generated certificates match up
-# with the published objects so that relying parties can find and
-# verify rpkid's published outputs.
-
-publication-base = publication/
-
-# Host and port on which pubd should listen for HTTPS service
-# requests. These should match pubd_base in the [myirbe] section.
-# You need to configure these.
-
-server-host = pubd.example.org
-server-port = 4402
-
-# Where pubd should look for BPKI certs and keys used in the
-# left-right protocol. The following values match where myirbe.py
-# will have placed things. Don't change these without a reason.
-
-bpki-ta = bpki.myirbe/ca.cer
-pubd-cert = bpki.myirbe/pubd.cer
-pubd-key = bpki.myirbe/pubd.key
-irbe-cert = bpki.myirbe/irbe.cer
-
-#################################################################
-
-[irbe_cli]
-
-# HTTPS service URL for rpkid
-
-rpkid-url = https://rpkid.example.org:4404/left-right/
-
-# BPKI certificates and keys for talking to rpkid
-
-rpkid-bpki-ta = bpki.myirbe/ca.cer
-rpkid-irbe-key = bpki.myirbe/irbe.key
-rpkid-irbe-cert = bpki.myirbe/irbe.cer
-rpkid-cert = bpki.myirbe/rpkid.cer
-
-# HTTPS service URL for pubd
-
-pubd-url = https://localhost:4402/control/
-
-# BPKI certificates and keys for talking to pubd
-
-pubd-bpki-ta = bpki.myirbe/ca.cer
-pubd-irbe-key = bpki.myirbe/irbe.key
-pubd-irbe-cert = bpki.myirbe/irbe.cer
-pubd-cert = bpki.myirbe/pubd.cer
-
-#################################################################
-
-# You don't need to run rootd unless you're IANA, are certifying
-# private address space, or are an RIR which refuses to accept IANA as
-# the root of the public address hierarchy.
-#
-# Ok, if that wasn't enough to scare you off: rootd is a kludge, and
-# needs to be rewritten, or, better, merged into rpkid. It does a
-# number of things wrong, and requires far too many configuration
-# parameters. You have been warned....
-
-[rootd]
-
-# BPKI certificates and keys for rootd
-
-bpki-ta = bpki.myirbe/ca.cer
-rootd-bpki-crl = bpki.myirbe/ca.crl
-rootd-bpki-cert = bpki.myirbe/rootd.cer
-rootd-bpki-key = bpki.myirbe/rootd.key
-child-bpki-cert = bpki.myirbe/child.cer
-
-# Server port on which rootd should listen.
-
-server-port = 4401
-
-# Where rootd should write its output. Yes, rootd should be using
-# pubd instead of publishing directly, but it doesn't.
-
-rpki-root-dir = publication/
-
-# rsync URI for directory containing rootd's outputs
-
-rpki-base-uri = rsync://rpki.example.org/Me/
-
-# rsync URI for rootd's root (self-signed) RPKI certificate
-
-rpki-root-cert-uri = rsync://rpki.example.org/Me/root.cer
-
-# Private key corresponding to rootd's root RPKI certificate
-
-rpki-root-key = bpki.myirbe/ca.key
-
-# Filename (as opposed to rsync URI) of rootd's root RPKI certificate
-
-rpki-root-cert = publication/root.cer
-
-# Where rootd should stash a copy of the PKCS #10 request it gets from
-# its one (and only) child
-
-rpki-subject-pkcs10 = rootd.subject.pkcs10
-
-# Lifetime of the one and only certificate rootd issues
-
-rpki-subject-lifetime = 30d
-
-# Filename (relative to rootd-base-uri and rpki-root-dir) of the CRL
-# for rootd's root RPKI certificate
-
-rpki-root-crl = root.crl
-
-# Filename (relative to rootd-base-uri and rpki-root-dir) of the
-# manifest for rootd's root RPKI certificate
-
-rpki-root-manifest = root.mnf
-
-# Up-down protocol class name for RPKI certificate rootd issues to its
-# one (and only) child
-
-rpki-class-name = Me
-
-# Filename (relative to rootd-base-uri and rpki-root-dir) of the one
-# (and only) RPKI certificate rootd issues
-
-rpki-subject-cert = Me.cer
-
-# The last four paramters in this section are really parameters for
-# myirbe.py to use when constructing rootd's root RPKI certificate,
-# via an indirection hack in the OpenSSL voodoo portion of this file.
-# Don't ask why some of these are duplicated from other paramters in
-# this section, you don't want to know (really, you don't).
-
-# ASNs to include in rootd's root RPKI certificate, in openssl.conf format
-
-root_cert_asns = AS:0-4294967295
-
-# IP addresses to include in rootd's root RPKI certificate, in
-# openssl.conf format
-
-root_cert_addrs = IPv4:0.0.0.0/0,IPv6:0::/0
-
-# Whatever you put in rpki-base-uri, earlier in this section
-
-root_cert_sia = rsync://rpki.example.org/Me/
-
-# root_cert_sia + rpki-root-manifest
-
-root_cert_manifest = rsync://rpki.example.org/Me/root.mnf
-
-#################################################################
-
-# Constants for OpenSSL voodoo portion of this file, to make them
-# easier to find.
-
-[constants]
-
-# Digest algorithm. Don't change this.
-
-digest = sha256
-
-# RSA key length. Don't change this.
-
-key_length = 2048
-
-# Lifetime of BPKI certificates (and rootd RPKI root certificate).
-# Don't change this unless you know what you're doing.
-
-cert_days = 365
-
-# Lifetime of BPKI CRLs. Don't change this unless you know what
-# you're doing.
-
-crl_days = 365
-
-#################################################################
-
-# The rest of this file is OpenSSL configuration voodoo. Don't touch
-# anything below here even if you -do- know what you're doing. Even
-# by OpenSSL standards, some of this is weird, and interacts in
-# non-obvious ways with code in myrpki.py and myirbe.py. If you touch
-# this stuff and something breaks, don't say you weren't warned.
-
-[req]
-default_bits = ${constants::key_length}
-default_md = ${constants::digest}
-distinguished_name = req_dn
-prompt = no
-encrypt_key = no
-
-[req_dn]
-CN = Dummy name for certificate request
-
-[ca_x509_ext_ee]
-subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always
-
-[ca_x509_ext_xcert0]
-basicConstraints = critical,CA:true,pathlen:0
-subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always
-
-[ca_x509_ext_xcert1]
-basicConstraints = critical,CA:true,pathlen:1
-subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always
-
-[ca_x509_ext_ca]
-basicConstraints = critical,CA:true
-subjectKeyIdentifier = hash
-authorityKeyIdentifier = keyid:always
-
-[ca]
-default_ca = ca
-dir = ${ENV::BPKI_DIRECTORY}
-new_certs_dir = $dir
-database = $dir/index
-certificate = $dir/ca.cer
-private_key = $dir/ca.key
-default_days = ${constants::cert_days}
-default_crl_days = ${constants::crl_days}
-default_md = ${constants::digest}
-policy = ca_dn_policy
-unique_subject = no
-serial = $dir/serial
-crlnumber = $dir/crl_number
-
-[ca_dn_policy]
-countryName = optional
-stateOrProvinceName = optional
-localityName = optional
-organizationName = optional
-organizationalUnitName = optional
-commonName = supplied
-emailAddress = optional
-givenName = optional
-surname = optional
-
-[rootd_x509_extensions]
-basicConstraints = critical,CA:true
-subjectKeyIdentifier = hash
-keyUsage = critical,keyCertSign,cRLSign
-subjectInfoAccess = 1.3.6.1.5.5.7.48.5;URI:${rootd::root_cert_sia},1.3.6.1.5.5.7.48.10;URI:${rootd::root_cert_manifest}
-sbgp-autonomousSysNum = critical,${rootd::root_cert_asns}
-sbgp-ipAddrBlock = critical,${rootd::root_cert_addrs}
-certificatePolicies = critical,1.3.6.1.5.5.7.14.2
diff --git a/myrpki/examples/parents.csv b/myrpki/examples/parents.csv
deleted file mode 100644
index f92eddeb..00000000
--- a/myrpki/examples/parents.csv
+++ /dev/null
@@ -1,8 +0,0 @@
-# $Id$
-#
-# Syntax: <parent_handle> <service_uri> <cms_bpki_cert_filename> <https_bpki_cert_filename> <myhandle> <sia_base>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-Mom https://localhost:4414/up-down/Mom/Becca Mom.ta.cer Mom.rpkid.cer Becca rsync://rpki.example.org/Me/
diff --git a/myrpki/examples/prefixes.csv b/myrpki/examples/prefixes.csv
deleted file mode 100644
index 160f9339..00000000
--- a/myrpki/examples/prefixes.csv
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Id$
-#
-# Syntax: <child_handle> <prefix>/<length>
-# or: <child_handle> <min>-<max>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-Alice 192.0.2.0/27
-Bob 192.0.2.44-192.0.2.100
-Bob 10.0.0.0/8
diff --git a/myrpki/examples/pubclients.csv b/myrpki/examples/pubclients.csv
deleted file mode 100644
index 6336a1a6..00000000
--- a/myrpki/examples/pubclients.csv
+++ /dev/null
@@ -1,10 +0,0 @@
-# $Id$
-#
-# Syntax: <client_handle> <bpki_cert_filename> <sia_base>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-Me bpki.myrpki/ca.cer rsync://rpki.example.org/Me/
-Me/Alice pubd-client-certs/Alice.cer rsync://rpki.example.org/Me/Alice/
-Me/Bob pubd-client-certs/Bob.cer rsync://rpki.example.org/Me/Bob/
diff --git a/myrpki/examples/roas.csv b/myrpki/examples/roas.csv
deleted file mode 100644
index 4343ada0..00000000
--- a/myrpki/examples/roas.csv
+++ /dev/null
@@ -1,8 +0,0 @@
-# $Id$
-#
-# Syntax: <prefix>/<length>-<maxlength> <asn> <group>
-#
-# NB: Comment lines are not allowed in these files, this one is only
-# present to explain the example
-#
-10.3.0.44/32 666 Mom
diff --git a/myrpki/examples/rsyncd.conf b/myrpki/examples/rsyncd.conf
deleted file mode 100644
index d0a9cd97..00000000
--- a/myrpki/examples/rsyncd.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-# $Id$
-#
-# Sample rsyncd.conf file for use with pubd. You may need to
-# customize this for the conventions on your system. See the rsync
-# and rsyncd.conf manual pages for a complete explanation of how to
-# configure rsyncd, this is just a simple configuration to get you
-# started.
-#
-# There are two parameters in the following which you should set to
-# appropriate values for your system:
-#
-# "myname" is the rsync module name to configure, as in
-# "rsync://rpki.example.org/myname/"
-#
-# "/some/where/publication" is the absolute pathname of the directory
-# where you told pubd to place its outputs (see the publication_base
-# parameter in the [pubd] section of myrpki.conf)
-#
-# You may need to adjust other parameters for your system environment.
-
-pid file = /var/run/rsyncd.pid
-uid = nobody
-gid = nobody
-
-[myname]
- use chroot = no
- read only = yes
- transfer logging = yes
- path = /some/where/publication
- comment = RPKI Testbed
diff --git a/myrpki/myirbe.py b/myrpki/myirbe.py
deleted file mode 100644
index c2c92279..00000000
--- a/myrpki/myirbe.py
+++ /dev/null
@@ -1,512 +0,0 @@
-"""
-IRBE-side stuff for myrpki tools.
-
-The basic model here is that each entity with resources to certify
-runs the myrpki tool, but not all of them necessarily run their own
-RPKi engines. The entities that do run RPKI engines get data from the
-entities they host via the XML files output by the myrpki tool. Those
-XML files are the input to this script, which uses them to do all the
-work of constructing certificates, populating SQL databases, and so
-forth. A few operations (eg, BSC construction) generate data which
-has to be shipped back to the resource holder, which we do by updating
-the same XML file.
-
-In essence, the XML files are a sneakernet (or email, or carrier
-pigeon) communication channel between the resource holders and the
-RPKI engine operators.
-
-As a convenience, for the normal case where the RPKI engine operator
-is itself a resource holder, this script also runs the myrpki script
-directly to process the RPKI engine operator's own resources.
-
-Note that, due to the back and forth nature of some of these
-operations, it may take several cycles for data structures to stablize
-and everything to reach a steady state. This is normal.
-
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from __future__ import with_statement
-
-import lxml.etree, base64, subprocess, sys, os, time, re, getopt, warnings
-import rpki.https, rpki.config, rpki.resource_set, rpki.relaxng
-import rpki.exceptions, rpki.left_right, rpki.log, rpki.x509, rpki.async
-import myrpki, schema
-
-# Silence warning while loading MySQLdb in Python 2.6, sigh
-if hasattr(warnings, "catch_warnings"):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- import MySQLdb
-else:
- import MySQLdb
-
-def tag(t):
- """
- Wrap an element name in the right XML namespace goop.
- """
- return "{http://www.hactrn.net/uris/rpki/myrpki/}" + t
-
-def findbase64(tree, name, b64type = rpki.x509.X509):
- """
- Find and extract a base64-encoded XML element, if present.
- """
- x = tree.findtext(tag(name))
- return b64type(Base64 = x) if x else None
-
-# For simple cases we don't really care what these value are, so long
-# as we're consistant about them, so wiring them in is fine.
-
-bsc_handle = "bsc"
-repository_handle = "repository"
-
-os.environ["TZ"] = "UTC"
-time.tzset()
-
-rpki.log.use_syslog = False
-rpki.log.init("myirbe")
-
-cfg_file = "myrpki.conf"
-
-bpki_only = False
-
-opts, argv = getopt.getopt(sys.argv[1:], "bc:h?", ["bpki_only", "config=", "help"])
-for o, a in opts:
- if o in ("-b", "--bpki_only"):
- bpki_only = True
- elif o in ("-c", "--config"):
- cfg_file = a
- elif o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
-
-cfg = rpki.config.parser(cfg_file, "myirbe")
-
-cfg.set_global_flags()
-
-myrpki.openssl = cfg.get("openssl", "openssl", "myrpki")
-
-handle = cfg.get("handle", cfg.get("handle", "Amnesiac", "myrpki"))
-
-want_pubd = cfg.getboolean("want_pubd", False)
-want_rootd = cfg.getboolean("want_rootd", False)
-
-bpki_modified = False
-
-bpki = myrpki.CA(cfg_file, cfg.get("bpki_directory"))
-bpki_modified |= bpki.setup(cfg.get("bpki_ta_dn", "/CN=%s BPKI TA" % handle))
-bpki_modified |= bpki.ee( cfg.get("bpki_rpkid_ee_dn", "/CN=%s rpkid EE" % handle), "rpkid")
-bpki_modified |= bpki.ee( cfg.get("bpki_irdbd_ee_dn", "/CN=%s irdbd EE" % handle), "irdbd")
-bpki_modified |= bpki.ee( cfg.get("bpki_irbe_ee_dn", "/CN=%s irbe EE" % handle), "irbe")
-if want_pubd:
- bpki_modified |= bpki.ee( cfg.get("bpki_pubd_ee_dn", "/CN=%s pubd EE" % handle), "pubd")
-if want_rootd:
- bpki_modified |= bpki.ee( cfg.get("bpki_rootd_ee_dn", "/CN=%s rootd EE" % handle), "rootd")
-
-if bpki_modified:
- print "BPKI (re)initialized. You need to (re)start daemons before continuing."
-
-if bpki_modified or bpki_only:
- sys.exit()
-
-# Default values for CRL parameters are very low, for testing.
-
-self_crl_interval = cfg.getint("self_crl_interval", 900)
-self_regen_margin = cfg.getint("self_regen_margin", 300)
-pubd_base = cfg.get("pubd_base").rstrip("/") + "/"
-rpkid_base = cfg.get("rpkid_base").rstrip("/") + "/"
-
-# Nasty regexp for parsing rpkid's up-down service URLs.
-
-updown_regexp = re.compile(re.escape(rpkid_base) + "up-down/([-A-Z0-9_]+)/([-A-Z0-9_]+)$", re.I)
-
-# Wrappers to simplify calling rpkid and pubd.
-
-call_rpkid = rpki.async.sync_wrapper(rpki.https.caller(
- proto = rpki.left_right,
- client_key = rpki.x509.RSA( PEM_file = bpki.dir + "/irbe.key"),
- client_cert = rpki.x509.X509(PEM_file = bpki.dir + "/irbe.cer"),
- server_ta = rpki.x509.X509(PEM_file = bpki.cer),
- server_cert = rpki.x509.X509(PEM_file = bpki.dir + "/rpkid.cer"),
- url = rpkid_base + "left-right"))
-
-if want_pubd:
-
- call_pubd = rpki.async.sync_wrapper(rpki.https.caller(
- proto = rpki.publication,
- client_key = rpki.x509.RSA( PEM_file = bpki.dir + "/irbe.key"),
- client_cert = rpki.x509.X509(PEM_file = bpki.dir + "/irbe.cer"),
- server_ta = rpki.x509.X509(PEM_file = bpki.cer),
- server_cert = rpki.x509.X509(PEM_file = bpki.dir + "/pubd.cer"),
- url = pubd_base + "control"))
-
- # Make sure that pubd's BPKI CRL is up to date.
-
- call_pubd(rpki.publication.config_elt.make_pdu(
- action = "set",
- bpki_crl = rpki.x509.CRL(PEM_file = bpki.crl)))
-
-irdbd_cfg = rpki.config.parser(cfg.get("irdbd_conf", cfg_file), "irdbd")
-
-db = MySQLdb.connect(user = irdbd_cfg.get("sql-username"),
- db = irdbd_cfg.get("sql-database"),
- passwd = irdbd_cfg.get("sql-password"))
-
-cur = db.cursor()
-
-xmlfiles = []
-
-# If [myrpki] section is present in config file, run myrpki.py
-# internally, as a convenience, and include its output at the head of
-# our list of XML files to process.
-
-if cfg.has_section("myrpki"):
- myrpki.main(("-c", cfg_file))
- my_xmlfile = cfg.get("xml_filename", None, "myrpki")
- assert my_xmlfile is not None
- xmlfiles.append(my_xmlfile)
-
-# Add any other XML files specified on the command line
-
-xmlfiles.extend(argv)
-
-my_handle = None
-
-for xmlfile in xmlfiles:
-
- # Parse XML file and validate it against our scheme
-
- tree = lxml.etree.parse(xmlfile).getroot()
- try:
- schema.myrpki.assertValid(tree)
- except lxml.etree.DocumentInvalid:
- print lxml.etree.tostring(tree, pretty_print = True)
- raise
-
- handle = tree.get("handle")
-
- if xmlfile == my_xmlfile:
- my_handle = handle
-
- # Update IRDB with parsed resource and roa-request data.
-
- cur.execute(
- """
- DELETE
- FROM roa_request_prefix
- USING roa_request, roa_request_prefix
- WHERE roa_request.roa_request_id = roa_request_prefix.roa_request_id AND roa_request.roa_request_handle = %s
- """, (handle,))
-
- cur.execute("DELETE FROM roa_request WHERE roa_request.roa_request_handle = %s", (handle,))
-
- for x in tree.getiterator(tag("roa_request")):
- cur.execute("INSERT roa_request (roa_request_handle, asn) VALUES (%s, %s)", (handle, x.get("asn")))
- roa_request_id = cur.lastrowid
- for version, prefix_set in ((4, rpki.resource_set.roa_prefix_set_ipv4(x.get("v4"))), (6, rpki.resource_set.roa_prefix_set_ipv6(x.get("v6")))):
- if prefix_set:
- cur.executemany("INSERT roa_request_prefix (roa_request_id, prefix, prefixlen, max_prefixlen, version) VALUES (%s, %s, %s, %s, %s)",
- ((roa_request_id, p.prefix, p.prefixlen, p.max_prefixlen, version) for p in prefix_set))
-
- cur.execute(
- """
- DELETE
- FROM registrant_asn
- USING registrant, registrant_asn
- WHERE registrant.registrant_id = registrant_asn.registrant_id AND registrant.registry_handle = %s
- """ , (handle,))
-
- cur.execute(
- """
- DELETE FROM registrant_net USING registrant, registrant_net
- WHERE registrant.registrant_id = registrant_net.registrant_id AND registrant.registry_handle = %s
- """ , (handle,))
-
- cur.execute("DELETE FROM registrant WHERE registrant.registry_handle = %s" , (handle,))
-
- for x in tree.getiterator(tag("child")):
- child_handle = x.get("handle")
- asns = rpki.resource_set.resource_set_as(x.get("asns"))
- ipv4 = rpki.resource_set.resource_set_ipv4(x.get("v4"))
- ipv6 = rpki.resource_set.resource_set_ipv6(x.get("v6"))
-
- cur.execute("INSERT registrant (registrant_handle, registry_handle, registrant_name, valid_until) VALUES (%s, %s, %s, %s)",
- (child_handle, handle, child_handle, rpki.sundial.datetime.fromXMLtime(x.get("valid_until")).to_sql()))
- child_id = cur.lastrowid
- if asns:
- cur.executemany("INSERT registrant_asn (start_as, end_as, registrant_id) VALUES (%s, %s, %s)",
- ((a.min, a.max, child_id) for a in asns))
- if ipv4:
- cur.executemany("INSERT registrant_net (start_ip, end_ip, version, registrant_id) VALUES (%s, %s, 4, %s)",
- ((a.min, a.max, child_id) for a in ipv4))
- if ipv6:
- cur.executemany("INSERT registrant_net (start_ip, end_ip, version, registrant_id) VALUES (%s, %s, 6, %s)",
- ((a.min, a.max, child_id) for a in ipv6))
-
- db.commit()
-
- # Check for certificates before attempting anything else
-
- hosted_cacert = findbase64(tree, "bpki_ca_certificate")
- if not hosted_cacert:
- print "Nothing else I can do without a trust anchor for the entity I'm hosting."
- continue
-
- rpkid_xcert = rpki.x509.X509(PEM_file = bpki.fxcert(handle + ".cacert.cer",
- hosted_cacert.get_PEM(),
- path_restriction = 1))
-
- # See what rpkid and pubd already have on file for this entity.
-
- if want_pubd:
- client_pdus = dict((x.client_handle, x)
- for x in call_pubd(rpki.publication.client_elt.make_pdu(action = "list"))
- if isinstance(x, rpki.publication.client_elt))
-
- rpkid_reply = call_rpkid(
- rpki.left_right.self_elt.make_pdu( action = "get", tag = "self", self_handle = handle),
- rpki.left_right.bsc_elt.make_pdu( action = "list", tag = "bsc", self_handle = handle),
- rpki.left_right.repository_elt.make_pdu(action = "list", tag = "repository", self_handle = handle),
- rpki.left_right.parent_elt.make_pdu( action = "list", tag = "parent", self_handle = handle),
- rpki.left_right.child_elt.make_pdu( action = "list", tag = "child", self_handle = handle))
-
- self_pdu = rpkid_reply[0]
- bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
- repository_pdus = dict((x.repository_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.repository_elt))
- parent_pdus = dict((x.parent_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.parent_elt))
- child_pdus = dict((x.child_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.child_elt))
-
- pubd_query = []
- rpkid_query = []
-
- # There should be exactly one <self/> object per hosted entity, by definition
-
- if (isinstance(self_pdu, rpki.left_right.report_error_elt) or
- self_pdu.crl_interval != self_crl_interval or
- self_pdu.regen_margin != self_regen_margin or
- self_pdu.bpki_cert != rpkid_xcert):
- rpkid_query.append(rpki.left_right.self_elt.make_pdu(
- action = "create" if isinstance(self_pdu, rpki.left_right.report_error_elt) else "set",
- tag = "self",
- self_handle = handle,
- bpki_cert = rpkid_xcert,
- crl_interval = self_crl_interval,
- regen_margin = self_regen_margin))
-
- # In general we only need one <bsc/> per <self/>. BSC objects are a
- # little unusual in that the PKCS #10 subelement is generated by rpkid
- # in response to generate_keypair, so there's more of a separation
- # between create and set than with other objects.
-
- bsc_cert = findbase64(tree, "bpki_bsc_certificate")
- bsc_crl = findbase64(tree, "bpki_crl", rpki.x509.CRL)
-
- bsc_pdu = bsc_pdus.pop(bsc_handle, None)
-
- if bsc_pdu is None:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
- action = "create",
- tag = "bsc",
- self_handle = handle,
- bsc_handle = bsc_handle,
- generate_keypair = "yes"))
- elif bsc_pdu.signing_cert != bsc_cert or bsc_pdu.signing_cert_crl != bsc_crl:
- rpkid_query.append(rpki.left_right.bsc_elt.make_pdu(
- action = "set",
- tag = "bsc",
- self_handle = handle,
- bsc_handle = bsc_handle,
- signing_cert = bsc_cert,
- signing_cert_crl = bsc_crl))
-
- rpkid_query.extend(rpki.left_right.bsc_elt.make_pdu(
- action = "destroy", self_handle = handle, bsc_handle = b) for b in bsc_pdus)
-
- bsc_req = None
-
- if bsc_pdu and bsc_pdu.pkcs10_request:
- bsc_req = bsc_pdu.pkcs10_request
-
- # In general we need one <repository/> per publication daemon with
- # whom this <self/> has a relationship. In practice there is rarely
- # (never?) a good reason for a single <self/> to use multiple
- # publication services, so in normal use we only need one
- # <repository/> object. If for some reason you really need more
- # than this, you'll have to hack.
-
- repository_cert = findbase64(tree, "bpki_repository_certificate")
- if repository_cert:
-
- repository_pdu = repository_pdus.pop(repository_handle, None)
- repository_uri = pubd_base + "client/" + tree.get("repository_handle")
-
- if (repository_pdu is None or
- repository_pdu.bsc_handle != bsc_handle or
- repository_pdu.peer_contact_uri != repository_uri or
- repository_pdu.bpki_cert != repository_cert):
- rpkid_query.append(rpki.left_right.repository_elt.make_pdu(
- action = "create" if repository_pdu is None else "set",
- tag = repository_handle,
- self_handle = handle,
- repository_handle = repository_handle,
- bsc_handle = bsc_handle,
- peer_contact_uri = repository_uri,
- bpki_cert = repository_cert))
-
- rpkid_query.extend(rpki.left_right.repository_elt.make_pdu(
- action = "destroy", self_handle = handle, repository_handle = r) for r in repository_pdus)
-
- # <parent/> setup code here used to be ridiculously complex. Most
- # of the insanity was due to a misguided attempt to deduce pubd
- # setup from other data; now that pubd setup is driven by
- # pubclients.csv, parent setup should be relatively straightforward,
- # but beware of lingering excessive cleverness in anything dealing
- # with parent objects in this script.
-
- for parent in tree.getiterator(tag("parent")):
-
- parent_handle = parent.get("handle")
- parent_pdu = parent_pdus.pop(parent_handle, None)
- parent_uri = parent.get("service_uri")
- parent_myhandle = parent.get("myhandle")
- parent_sia_base = parent.get("sia_base")
- parent_cms_cert = findbase64(parent, "bpki_cms_certificate")
- parent_https_cert = findbase64(parent, "bpki_https_certificate")
-
- if (parent_pdu is None or
- parent_pdu.bsc_handle != bsc_handle or
- parent_pdu.repository_handle != repository_handle or
- parent_pdu.peer_contact_uri != parent_uri or
- parent_pdu.sia_base != parent_sia_base or
- parent_pdu.sender_name != parent_myhandle or
- parent_pdu.recipient_name != parent_handle or
- parent_pdu.bpki_cms_cert != parent_cms_cert or
- parent_pdu.bpki_https_cert != parent_https_cert):
- rpkid_query.append(rpki.left_right.parent_elt.make_pdu(
- action = "create" if parent_pdu is None else "set",
- tag = parent_handle,
- self_handle = handle,
- parent_handle = parent_handle,
- bsc_handle = bsc_handle,
- repository_handle = repository_handle,
- peer_contact_uri = parent_uri,
- sia_base = parent_sia_base,
- sender_name = parent_myhandle,
- recipient_name = parent_handle,
- bpki_cms_cert = parent_cms_cert,
- bpki_https_cert = parent_https_cert))
-
- rpkid_query.extend(rpki.left_right.parent_elt.make_pdu(
- action = "destroy", self_handle = handle, parent_handle = p) for p in parent_pdus)
-
- # Children are simpler than parents, because they call us, so no URL
- # to construct and figuring out what certificate to use is their
- # problem, not ours.
-
- for child in tree.getiterator(tag("child")):
-
- child_handle = child.get("handle")
- child_pdu = child_pdus.pop(child_handle, None)
- child_cert = findbase64(child, "bpki_certificate")
-
- if (child_pdu is None or
- child_pdu.bsc_handle != bsc_handle or
- child_pdu.bpki_cert != child_cert):
- rpkid_query.append(rpki.left_right.child_elt.make_pdu(
- action = "create" if child_pdu is None else "set",
- tag = child_handle,
- self_handle = handle,
- child_handle = child_handle,
- bsc_handle = bsc_handle,
- bpki_cert = child_cert))
-
- rpkid_query.extend(rpki.left_right.child_elt.make_pdu(
- action = "destroy", self_handle = handle, child_handle = c) for c in child_pdus)
-
- # Publication setup, used to be inferred (badly) from parent setup,
- # now handled explictly via yet another freaking .csv file.
-
- if want_pubd:
-
- for client_handle, client_bpki_cert, client_base_uri in myrpki.csv_open(cfg.get("pubclients_csv", "pubclients.csv")):
-
- if os.path.exists(client_bpki_cert):
-
- client_pdu = client_pdus.pop(client_handle, None)
-
- client_bpki_cert = rpki.x509.X509(PEM_file = bpki.xcert(client_bpki_cert))
-
- if (client_pdu is None or
- client_pdu.base_uri != client_base_uri or
- client_pdu.bpki_cert != client_bpki_cert):
- pubd_query.append(rpki.publication.client_elt.make_pdu(
- action = "create" if client_pdu is None else "set",
- client_handle = client_handle,
- bpki_cert = client_bpki_cert,
- base_uri = client_base_uri))
-
- pubd_query.extend(rpki.publication.client_elt.make_pdu(
- action = "destroy", client_handle = p) for p in client_pdus)
-
- # If we changed anything, ship updates off to daemons
-
- if rpkid_query:
- rpkid_reply = call_rpkid(*rpkid_query)
- bsc_pdus = dict((x.bsc_handle, x) for x in rpkid_reply if isinstance(x, rpki.left_right.bsc_elt))
- if bsc_handle in bsc_pdus and bsc_pdus[bsc_handle].pkcs10_request:
- bsc_req = bsc_pdus[bsc_handle].pkcs10_request
- for r in rpkid_reply:
- assert not isinstance(r, rpki.left_right.report_error_elt)
-
- if pubd_query:
- assert want_pubd
- pubd_reply = call_pubd(*pubd_query)
- for r in pubd_reply:
- assert not isinstance(r, rpki.publication.report_error_elt)
-
- # Rewrite XML.
-
- e = tree.find(tag("bpki_bsc_pkcs10"))
- if e is None and bsc_req is not None:
- e = lxml.etree.SubElement(tree, "bpki_bsc_pkcs10")
- elif bsc_req is None:
- tree.remove(e)
-
- if bsc_req is not None:
- assert e is not None
- e.text = bsc_req.get_Base64()
-
- # Something weird going on here with lxml linked against recent
- # versions of libxml2. Looks like modifying the tree above somehow
- # produces validation errors, but it works fine if we convert it to
- # a string and parse it again. I'm not seeing any problems with any
- # of the other code that uses lxml to do validation, just this one
- # place. Weird. Kludge around it for now.
-
- tree = lxml.etree.fromstring(lxml.etree.tostring(tree))
-
- try:
- schema.myrpki.assertValid(tree)
- except lxml.etree.DocumentInvalid:
- print lxml.etree.tostring(tree, pretty_print = True)
- raise
-
- lxml.etree.ElementTree(tree).write(xmlfile + ".tmp", pretty_print = True)
- os.rename(xmlfile + ".tmp", xmlfile)
-
-db.close()
diff --git a/myrpki/myrpki.py b/myrpki/myrpki.py
deleted file mode 100644
index 7937521d..00000000
--- a/myrpki/myrpki.py
+++ /dev/null
@@ -1,644 +0,0 @@
-"""
-Read an OpenSSL-style config file and a bunch of .csv files to find
-out about parents and children and resources and ROA requests, oh my.
-Run OpenSSL command line tool to construct BPKI certificates,
-including cross-certification of other entities' BPKI certificates.
-
-Package up all of the above as a single XML file which user can then
-ship off to the IRBE. If an XML file already exists, check it for
-data coming back from the IRBE (principally PKCS #10 requests for our
-BSC) and update it with current data.
-
-The general idea here is that this one XML file contains all of the
-data that needs to be exchanged as part of ordinary update operations;
-each party updates it as necessary, then ships it to the other via
-some secure channel: carrier pigeon, USB stick, gpg-protected email,
-we don't really care.
-
-This one program is written a little differently from all the other
-Python RPKI programs. This one program is intended to run as a
-stand-alone script, without the other programs present. It does
-require a reasonably up-to-date version of the OpenSSL command line
-tool (the one built as a side effect of building rcynic will do), but
-it does -not- require POW or any Python libraries beyond what ships
-with Python 2.5. So this script uses xml.etree from the Python
-standard libraries instead of lxml.etree, which sacrifices XML schema
-validation support in favor of portability, and so forth.
-
-To make things a little weirder, as a convenience to IRBE operators,
-this script can itself be loaded as a Python module and invoked as
-part of another program. This requires a few minor contortions, but
-avoids duplicating common code.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-# Only standard Python libraries for this program, please.
-
-import subprocess, csv, re, os, getopt, sys, ConfigParser, base64
-
-from xml.etree.ElementTree import Element, SubElement, ElementTree
-
-# Our XML namespace.
-
-namespace = "http://www.hactrn.net/uris/rpki/myrpki/"
-
-# Dialect for our use of CSV files, here to make it easy to change if
-# your site needs to do something different. See doc for the csv
-# module in the Python standard libraries for details if you need to
-# customize this.
-
-csv_dialect = csv.get_dialect("excel-tab")
-
-# Whether to include incomplete entries when rendering to XML.
-
-allow_incomplete = False
-
-# Whether to whine about incomplete entries while rendering to XML.
-
-whine = False
-
-class comma_set(set):
- """
- Minor customization of set(), to provide a print syntax.
- """
-
- def __str__(self):
- return ",".join(self)
-
-class roa_request(object):
- """
- Representation of a ROA request.
- """
-
- v4re = re.compile("^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+(-[0-9]+)?$", re.I)
- v6re = re.compile("^([0-9a-f]{0,4}:){0,15}[0-9a-f]{0,4}/[0-9]+(-[0-9]+)?$", re.I)
-
- def __init__(self, asn, group):
- self.asn = asn
- self.group = group
- self.v4 = comma_set()
- self.v6 = comma_set()
-
- def __repr__(self):
- s = "<%s asn %s group %s" % (self.__class__.__name__, self.asn, self.group)
- if self.v4:
- s += " v4 %s" % self.v4
- if self.v6:
- s += " v6 %s" % self.v6
- return s + ">"
-
- def add(self, prefix):
- """
- Add one prefix to this ROA request.
- """
- if self.v4re.match(prefix):
- self.v4.add(prefix)
- elif self.v6re.match(prefix):
- self.v6.add(prefix)
- else:
- raise RuntimeError, "Bad prefix syntax: %r" % (prefix,)
-
- def xml(self, e):
- """
- Generate XML element represeting representing this ROA request.
- """
- SubElement(e, "roa_request",
- asn = self.asn,
- v4 = str(self.v4),
- v6 = str(self.v6))
-
-class roa_requests(dict):
- """
- Database of ROA requests.
- """
-
- def add(self, asn, group, prefix):
- """
- Add one <ASN, group, prefix> set to ROA request database.
- """
- key = (asn, group)
- if key not in self:
- self[key] = roa_request(asn, group)
- self[key].add(prefix)
-
- def xml(self, e):
- """
- Render ROA requests as XML elements.
- """
- for r in self.itervalues():
- r.xml(e)
-
- @classmethod
- def from_csv(cls, roa_csv_file):
- """
- Parse ROA requests from CSV file.
- """
- self = cls()
- # format: p/n-m asn group
- for pnm, asn, group in csv_open(roa_csv_file):
- self.add(asn = asn, group = group, prefix = pnm)
- return self
-
-class child(object):
- """
- Representation of one child entity.
- """
-
- v4re = re.compile("^(([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+)|(([0-9]{1,3}\.){3}[0-9]{1,3}-([0-9]{1,3}\.){3}[0-9]{1,3})$", re.I)
- v6re = re.compile("^(([0-9a-f]{0,4}:){0,15}[0-9a-f]{0,4}/[0-9]+)|(([0-9a-f]{0,4}:){0,15}[0-9a-f]{0,4}-([0-9a-f]{0,4}:){0,15}[0-9a-f]{0,4})$", re.I)
-
- def __init__(self, handle):
- self.handle = handle
- self.asns = comma_set()
- self.v4 = comma_set()
- self.v6 = comma_set()
- self.validity = None
- self.bpki_certificate = None
-
- def __repr__(self):
- s = "<%s %s" % (self.__class__.__name__, self.handle)
- if self.asns:
- s += " asn %s" % self.asns
- if self.v4:
- s += " v4 %s" % self.v4
- if self.v6:
- s += " v6 %s" % self.v6
- if self.validity:
- s += " valid %s" % self.validity
- if self.bpki_certificate:
- s += " cert %s" % self.bpki_certificate
- return s + ">"
-
- def add(self, prefix = None, asn = None, validity = None, bpki_certificate = None):
- """
- Add prefix, autonomous system number, validity date, or BPKI
- certificate for this child.
- """
- if prefix is not None:
- if self.v4re.match(prefix):
- self.v4.add(prefix)
- elif self.v6re.match(prefix):
- self.v6.add(prefix)
- else:
- raise RuntimeError, "Bad prefix syntax: %r" % (prefix,)
- if asn is not None:
- self.asns.add(asn)
- if validity is not None:
- self.validity = validity
- if bpki_certificate is not None:
- self.bpki_certificate = bpki_certificate
-
- def xml(self, e):
- """
- Render this child as an XML element.
- """
- complete = self.bpki_certificate and self.validity
- if whine and not complete:
- print "Incomplete child entry %s" % self
- if complete or allow_incomplete:
- e = SubElement(e, "child",
- handle = self.handle,
- valid_until = self.validity,
- asns = str(self.asns),
- v4 = str(self.v4),
- v6 = str(self.v6))
- if self.bpki_certificate:
- PEMElement(e, "bpki_certificate", self.bpki_certificate)
-
-class children(dict):
- """
- Database of children.
- """
-
- def add(self, handle, prefix = None, asn = None, validity = None, bpki_certificate = None):
- """
- Add resources to a child, creating the child object if necessary.
- """
- if handle not in self:
- self[handle] = child(handle)
- self[handle].add(prefix = prefix, asn = asn, validity = validity, bpki_certificate = bpki_certificate)
-
- def xml(self, e):
- """
- Render children database to XML.
- """
- for c in self.itervalues():
- c.xml(e)
-
- @classmethod
- def from_csv(cls, children_csv_file, prefix_csv_file, asn_csv_file, xcert):
- """
- Parse child resources, certificates, and validity dates from CSV files.
- """
- self = cls()
- # childname date pemfile
- for handle, date, pemfile in csv_open(children_csv_file):
- self.add(handle = handle, validity = date, bpki_certificate = xcert(pemfile))
- # childname p/n
- for handle, pn in csv_open(prefix_csv_file):
- self.add(handle = handle, prefix = pn)
- # childname asn
- for handle, asn in csv_open(asn_csv_file):
- self.add(handle = handle, asn = asn)
- return self
-
-class parent(object):
- """
- Representation of one parent entity.
- """
-
- def __init__(self, handle):
- self.handle = handle
- self.service_uri = None
- self.bpki_cms_certificate = None
- self.bpki_https_certificate = None
- self.myhandle = None
- self.sia_base = None
-
- def __repr__(self):
- s = "<%s %s" % (self.__class__.__name__, self.handle)
- if self.myhandle:
- s += " myhandle %s" % self.myhandle
- if self.service_uri:
- s += " uri %s" % self.service_uri
- if self.sia_base:
- s += " sia %s" % self.sia_base
- if self.bpki_cms_certificate:
- s += " cms %s" % self.bpki_cms_certificate
- if self.bpki_https_certificate:
- s += " https %s" % self.bpki_https_certificate
- return s + ">"
-
- def add(self, service_uri = None,
- bpki_cms_certificate = None,
- bpki_https_certificate = None,
- myhandle = None,
- sia_base = None):
- """
- Add service URI or BPKI certificates to this parent object.
- """
- if service_uri is not None:
- self.service_uri = service_uri
- if bpki_cms_certificate is not None:
- self.bpki_cms_certificate = bpki_cms_certificate
- if bpki_https_certificate is not None:
- self.bpki_https_certificate = bpki_https_certificate
- if myhandle is not None:
- self.myhandle = myhandle
- if sia_base is not None:
- self.sia_base = sia_base
-
- def xml(self, e):
- """
- Render this parent object to XML.
- """
- complete = self.bpki_cms_certificate and self.bpki_https_certificate and self.myhandle and self.service_uri and self.sia_base
- if whine and not complete:
- print "Incomplete parent entry %s" % self
- if complete or allow_incomplete:
- e = SubElement(e, "parent",
- handle = self.handle,
- myhandle = self.myhandle,
- service_uri = self.service_uri,
- sia_base = self.sia_base)
- if self.bpki_cms_certificate:
- PEMElement(e, "bpki_cms_certificate", self.bpki_cms_certificate)
- if self.bpki_https_certificate:
- PEMElement(e, "bpki_https_certificate", self.bpki_https_certificate)
-
-class parents(dict):
- """
- Database of parent objects.
- """
-
- def add(self, handle,
- service_uri = None,
- bpki_cms_certificate = None,
- bpki_https_certificate = None,
- myhandle = None,
- sia_base = None):
- """
- Add service URI or certificates to parent object, creating it if necessary.
- """
- if handle not in self:
- self[handle] = parent(handle)
- self[handle].add(service_uri = service_uri,
- bpki_cms_certificate = bpki_cms_certificate,
- bpki_https_certificate = bpki_https_certificate,
- myhandle = myhandle,
- sia_base = sia_base)
-
- def xml(self, e):
- for c in self.itervalues():
- c.xml(e)
-
- @classmethod
- def from_csv(cls, parents_csv_file, xcert):
- """
- Parse parent data from CSV file.
- """
- self = cls()
- # parentname service_uri parent_bpki_cms_pemfile parent_bpki_https_pemfile myhandle sia_base
- for handle, service_uri, parent_cms_pemfile, parent_https_pemfile, myhandle, sia_base in csv_open(parents_csv_file):
- self.add(handle = handle,
- service_uri = service_uri,
- bpki_cms_certificate = xcert(parent_cms_pemfile),
- bpki_https_certificate = xcert(parent_https_pemfile),
- myhandle = myhandle,
- sia_base = sia_base)
- return self
-
-def csv_open(filename):
- """
- Open a CSV file, with settings that make it a tab-delimited file.
- You may need to tweak this function for your environment, see the
- csv module in the Python standard libraries for details.
- """
- return csv.reader(open(filename, "rb"), dialect = csv_dialect)
-
-def PEMElement(e, tag, filename):
- """
- Create an XML element containing Base64 encoded data taken from a
- PEM file.
- """
- lines = open(filename).readlines()
- while lines:
- if lines.pop(0).startswith("-----BEGIN "):
- break
- while lines:
- if lines.pop(-1).startswith("-----END "):
- break
- SubElement(e, tag).text = "".join(line.strip() for line in lines)
-
-class CA(object):
- """
- Representation of one certification authority.
- """
-
- # Mapping of path restriction values we use to OpenSSL config file
- # section names.
-
- path_restriction = { 0 : "ca_x509_ext_xcert0",
- 1 : "ca_x509_ext_xcert1" }
-
- def __init__(self, cfg, dir):
- self.cfg = cfg
- self.dir = dir
- self.cer = dir + "/ca.cer"
- self.key = dir + "/ca.key"
- self.req = dir + "/ca.req"
- self.crl = dir + "/ca.crl"
- self.index = dir + "/index"
- self.serial = dir + "/serial"
- self.crlnum = dir + "/crl_number"
-
- self.env = { "PATH" : os.environ["PATH"],
- "BPKI_DIRECTORY" : dir,
- "RANDFILE" : ".OpenSSL.whines.unless.I.set.this" }
-
- def run_ca(self, *args):
- """
- Run OpenSSL "ca" command with tailored environment variables and common initial
- arguments.
- """
- cmd = (openssl, "ca", "-batch", "-config", self.cfg) + args
- subprocess.check_call(cmd, env = self.env)
-
- def run_req(self, key_file, req_file):
- """
- Run OpenSSL "req" command with tailored environment variables and common arguments.
- """
- if not os.path.exists(key_file) or not os.path.exists(req_file):
- subprocess.check_call((openssl, "req", "-new", "-sha256", "-newkey", "rsa:2048",
- "-config", self.cfg, "-keyout", key_file, "-out", req_file),
- env = self.env)
-
- @staticmethod
- def touch_file(filename, content = None):
- """
- Create dumb little text files expected by OpenSSL "ca" utility.
- """
- if not os.path.exists(filename):
- f = open(filename, "w")
- if content is not None:
- f.write(content)
- f.close()
-
- def setup(self, ca_name):
- """
- Set up this CA. ca_name is an X.509 distinguished name in
- /tag=val/tag=val format.
- """
-
- modified = False
-
- if not os.path.exists(self.dir):
- os.makedirs(self.dir)
- self.touch_file(self.index)
- self.touch_file(self.serial, "01\n")
- self.touch_file(self.crlnum, "01\n")
-
- self.run_req(key_file = self.key, req_file = self.req)
-
- if not os.path.exists(self.cer):
- modified = True
- self.run_ca("-selfsign", "-extensions", "ca_x509_ext_ca", "-subj", ca_name, "-in", self.req, "-out", self.cer)
-
- if not os.path.exists(self.crl):
- modified = True
- self.run_ca("-gencrl", "-out", self.crl)
-
- return modified
-
- def ee(self, ee_name, base_name):
- """
- Issue an end-enity certificate.
- """
- key_file = "%s/%s.key" % (self.dir, base_name)
- req_file = "%s/%s.req" % (self.dir, base_name)
- cer_file = "%s/%s.cer" % (self.dir, base_name)
- self.run_req(key_file = key_file, req_file = req_file)
- if not os.path.exists(cer_file):
- self.run_ca("-extensions", "ca_x509_ext_ee", "-subj", ee_name, "-in", req_file, "-out", cer_file)
- return True
- else:
- return False
-
- def bsc(self, pkcs10):
- """
- Issue BSC certificiate, if we have a PKCS #10 request for it.
- """
-
- if pkcs10 is None:
- return None, None
-
- pkcs10 = base64.b64decode(pkcs10)
-
- assert pkcs10
-
- p = subprocess.Popen((openssl, "dgst", "-md5"), stdin = subprocess.PIPE, stdout = subprocess.PIPE)
- hash = p.communicate(pkcs10)[0].strip()
- if p.wait() != 0:
- raise RuntimeError, "Couldn't hash PKCS#10 request"
-
- req_file = "%s/bsc.%s.req" % (self.dir, hash)
- cer_file = "%s/bsc.%s.cer" % (self.dir, hash)
-
- if not os.path.exists(cer_file):
-
- p = subprocess.Popen((openssl, "req", "-inform", "DER", "-out", req_file), stdin = subprocess.PIPE)
- p.communicate(pkcs10)
- if p.wait() != 0:
- raise RuntimeError, "Couldn't store PKCS #10 request"
-
- self.run_ca("-extensions", "ca_x509_ext_ee", "-in", req_file, "-out", cer_file)
-
- return req_file, cer_file
-
- def fxcert(self, filename, cert, path_restriction = 0):
- """
- Write PEM certificate to file, then cross-certify.
- """
- fn = os.path.join(self.dir, filename)
- f = open(fn, "w")
- f.write(cert)
- f.close()
- return self.xcert(fn, path_restriction)
-
- def xcert(self, cert, path_restriction = 0):
- """
- Cross-certify a certificate represented as a PEM file.
- """
-
- if not cert:
- return None
-
- if not os.path.exists(cert):
- #print "Certificate %s doesn't exist, skipping" % cert
- return None
-
- # Extract public key and subject name from PEM file and hash it so
- # we can use the result as a tag for cross-certifying this cert.
-
- p1 = subprocess.Popen((openssl, "x509", "-noout", "-pubkey", "-subject", "-in", cert), stdout = subprocess.PIPE)
- p2 = subprocess.Popen((openssl, "dgst", "-md5"), stdin = p1.stdout, stdout = subprocess.PIPE)
-
- xcert = "%s/xcert.%s.cer" % (self.dir, p2.communicate()[0].strip())
-
- if p1.wait() != 0 or p2.wait() != 0:
- raise RuntimeError, "Couldn't generate cross-certification tag for %r" % cert
-
- # Cross-certify the cert we were given, if we haven't already.
- # This only works for self-signed certs, due to limitations of the
- # OpenSSL command line tool, but that suffices for our purposes.
-
- if not os.path.exists(xcert):
- self.run_ca("-ss_cert", cert, "-out", xcert, "-extensions", self.path_restriction[path_restriction])
-
- return xcert
-
-def extract_resources():
- """
- Extract RFC 3779 resources from a certificate. Not written yet.
-
- """
- raise NotImplementedError
-
-
-def main(argv = ()):
- """
- Main program. Must be callable from other programs as well as being
- invoked directly when this module is run as a script.
- """
-
- cfg_file = "myrpki.conf"
- section = "myrpki"
-
- opts, argv = getopt.getopt(argv, "c:h:?", ["config=", "help"])
- for o, a in opts:
- if o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
- elif o in ("-c", "--config"):
- cfg_file = a
- if argv:
- raise RuntimeError, "Unexpected arguments %r" % (argv,)
-
- cfg = ConfigParser.RawConfigParser()
- cfg.readfp(open(cfg_file, "r"), cfg_file)
-
- my_handle = cfg.get(section, "handle")
- roa_csv_file = cfg.get(section, "roa_csv")
- children_csv_file = cfg.get(section, "children_csv")
- parents_csv_file = cfg.get(section, "parents_csv")
- prefix_csv_file = cfg.get(section, "prefix_csv")
- asn_csv_file = cfg.get(section, "asn_csv")
- bpki_dir = cfg.get(section, "bpki_directory")
- xml_filename = cfg.get(section, "xml_filename")
- repository_bpki_certificate = cfg.get(section, "repository_bpki_certificate")
- repository_handle = cfg.get(section, "repository_handle")
-
- global openssl
- openssl = cfg.get(section, "openssl") if cfg.has_option(section, "openssl") else "openssl"
-
- bpki = CA(cfg_file, bpki_dir)
- bpki.setup("/CN=%s TA" % my_handle)
-
- if os.path.exists(xml_filename):
- e = ElementTree(file = xml_filename).getroot()
- bsc_req, bsc_cer = bpki.bsc(e.findtext("{%s}%s" % (namespace, "bpki_bsc_pkcs10")))
- else:
- bsc_req, bsc_cer = None, None
-
- e = Element("myrpki", xmlns = namespace, version = "1", handle = my_handle, repository_handle = repository_handle)
-
- roa_requests.from_csv(roa_csv_file).xml(e)
-
- children.from_csv(
- children_csv_file = children_csv_file,
- prefix_csv_file = prefix_csv_file,
- asn_csv_file = asn_csv_file,
- xcert = bpki.xcert).xml(e)
-
- parents.from_csv(
- parents_csv_file = parents_csv_file,
- xcert = bpki.xcert).xml(e)
-
- PEMElement(e, "bpki_ca_certificate", bpki.cer)
- PEMElement(e, "bpki_crl", bpki.crl)
-
- if os.path.exists(repository_bpki_certificate):
- PEMElement(e, "bpki_repository_certificate", bpki.xcert(repository_bpki_certificate))
-
- if bsc_cer:
- PEMElement(e, "bpki_bsc_certificate", bsc_cer)
-
- if bsc_req:
- PEMElement(e, "bpki_bsc_pkcs10", bsc_req)
-
- # I still miss SYSCAL(RENMWO)
-
- ElementTree(e).write(xml_filename + ".tmp")
- os.rename(xml_filename + ".tmp", xml_filename)
-
-# When this file is run as a script, run main() with command line
-# arguments. main() can't use sys.argv directly as that might be the
-# command line for some other program that loads this module.
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/myrpki/rcynic.conf b/myrpki/rcynic.conf
deleted file mode 100644
index 02a2495b..00000000
--- a/myrpki/rcynic.conf
+++ /dev/null
@@ -1,11 +0,0 @@
-# $Id$
-
-[rcynic]
-xml-summary = rcynic.xml
-jitter = 0
-use-links = yes
-use-syslog = no
-use-stderr = yes
-log-level = log_debug
-
-trust-anchor = test/RIR/publication/root.cer
diff --git a/myrpki/ripe-to-csv.py b/myrpki/ripe-to-csv.py
deleted file mode 100644
index 8166d682..00000000
--- a/myrpki/ripe-to-csv.py
+++ /dev/null
@@ -1,133 +0,0 @@
-"""
-Parse a WHOIS research dump and write out (just) the RPKI-relevant
-fields in myrpki-format CSV syntax.
-
-NB: The input data for this script is publicly available via FTP, but
-you'll have to fetch the data from RIPE yourself, and be sure to see
-the terms and conditions referenced by the data file header comments.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import gzip, csv, myrpki
-
-class Handle(dict):
-
- want_tags = ()
-
- debug = True
-
- def set(self, tag, val):
- if tag in self.want_tags:
- self[tag] = "".join(val.split(" "))
-
- def check(self):
- for tag in self.want_tags:
- if not tag in self:
- return False
- if self.debug:
- self.log()
- return True
-
- def __repr__(self):
- return "<%s %s>" % (self.__class__.__name__,
- " ".join("%s:%s" % (tag, self.get(tag, "?"))
- for tag in self.want_tags))
-
- def log(self):
- print repr(self)
-
- def finish(self, ctx):
- self.check()
-
-class as_block(Handle):
- # This one is less useful than I had hoped, no useful links to owners
- want_tags = ("as-block", "mnt-by", "org", "mnt-lower")
-
-class as_set(Handle):
- # This is probably useless
- want_tags = ("as-set", "mnt-by", "members")
-
-class aut_num(Handle):
- want_tags = ("aut-num", "mnt-by", "as-name")
-
- def set(self, tag, val):
- if tag == "aut-num" and val.startswith("AS"):
- val = val[2:]
- Handle.set(self, tag, val)
-
- def finish(self, ctx):
- if self.check():
- ctx.asns.writerow((self["mnt-by"], self["aut-num"]))
-
-class inetnum(Handle):
- want_tags = ("inetnum", "mnt-by", "netname")
-
- def finish(self, ctx):
- if self.check():
- ctx.prefixes.writerow((self["mnt-by"], self["inetnum"]))
-
-class inet6num(Handle):
- want_tags = ("inet6num", "mnt-by", "netname")
-
- def finish(self, ctx):
- if self.check():
- ctx.prefixes.writerow((self["mnt-by"], self["inet6num"]))
-
-class main(object):
-
- types = dict((x.want_tags[0], x) for x in (as_block, as_set, aut_num, inetnum, inet6num))
-
- @staticmethod
- def csvout(fn):
- return csv.writer(open(fn, "w"), dialect = myrpki.csv_dialect)
-
- def finish_statement(self, done):
- if self.statement:
- tag, sep, val = self.statement.partition(":")
- assert sep, "Couldn't find separator in %r" % self.statement
- tag = tag.strip().lower()
- val = val.strip().upper()
- if self.cur is None:
- self.cur = self.types[tag]() if tag in self.types else False
- if self.cur is not False:
- self.cur.set(tag, val)
- if done and self.cur:
- self.cur.finish(self)
- self.cur = None
-
- #filenames = ("ripe.db.gz",)
- filenames = ("ripe.db.aut-num.gz", "ripe.db.inet6num.gz", "ripe.db.inetnum.gz")
-
- def __init__(self):
- self.asns = self.csvout("asns.csv")
- self.prefixes = self.csvout("prefixes.csv")
- for fn in self.filenames:
- f = gzip.open(fn)
- self.statement = ""
- self.cur = None
- for line in f:
- line = line.expandtabs().partition("#")[0].rstrip("\n")
- if line and not line[0].isalpha():
- self.statement += line[1:] if line[0] == "+" else line
- else:
- self.finish_statement(not line)
- self.statement = line
- self.finish_statement(True)
- f.close()
-
-main()
diff --git a/myrpki/rpki b/myrpki/rpki
deleted file mode 120000
index 168548eb..00000000
--- a/myrpki/rpki
+++ /dev/null
@@ -1 +0,0 @@
-../rpkid/rpki \ No newline at end of file
diff --git a/myrpki/schema.py b/myrpki/schema.py
deleted file mode 100644
index c371b45b..00000000
--- a/myrpki/schema.py
+++ /dev/null
@@ -1,199 +0,0 @@
-import lxml.etree
-myrpki = lxml.etree.RelaxNG(lxml.etree.fromstring('''<?xml version="1.0" encoding="UTF-8"?>
-<!--
- $Id: schema.rnc 2839 2009-10-27 18:53:00Z sra $
-
- RelaxNG Schema for MyRPKI XML messages
-
- libxml2 (including xmllint) only groks the XML syntax of RelaxNG, so
- run the compact syntax through trang to get XML syntax.
--->
-<grammar ns="http://www.hactrn.net/uris/rpki/myrpki/" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
- <define name="base64">
- <data type="base64Binary">
- <param name="maxLength">512000</param>
- </data>
- </define>
- <define name="object_handle">
- <data type="string">
- <param name="maxLength">255</param>
- <param name="pattern">[\-_A-Za-z0-9]*</param>
- </data>
- </define>
- <define name="pubd_handle">
- <data type="string">
- <param name="maxLength">255</param>
- <param name="pattern">[\-_A-Za-z0-9/]*</param>
- </data>
- </define>
- <define name="uri">
- <data type="anyURI">
- <param name="maxLength">4096</param>
- </data>
- </define>
- <define name="asn_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9]*</param>
- </data>
- </define>
- <define name="ipv4_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9/.]*</param>
- </data>
- </define>
- <define name="ipv6_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9/:a-fA-F]*</param>
- </data>
- </define>
- <start>
- <element name="myrpki">
- <attribute name="version">
- <data type="positiveInteger">
- <param name="maxInclusive">1</param>
- </data>
- </attribute>
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <attribute name="repository_handle">
- <ref name="pubd_handle"/>
- </attribute>
- <zeroOrMore>
- <ref name="roa_request_elt"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="child_elt"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="parent_elt"/>
- </zeroOrMore>
- <optional>
- <ref name="bpki_ca_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_crl_elt"/>
- </optional>
- <optional>
- <ref name="bpki_repository_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_bsc_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_bsc_pkcs10_elt"/>
- </optional>
- </element>
- </start>
- <define name="roa_request_elt">
- <element name="roa_request">
- <attribute name="asn">
- <data type="positiveInteger"/>
- </attribute>
- <attribute name="v4">
- <ref name="ipv4_list"/>
- </attribute>
- <attribute name="v6">
- <ref name="ipv6_list"/>
- </attribute>
- </element>
- </define>
- <define name="child_elt">
- <element name="child">
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <attribute name="valid_until">
- <data type="dateTime">
- <param name="pattern">.*Z</param>
- </data>
- </attribute>
- <optional>
- <attribute name="asns">
- <ref name="asn_list"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="v4">
- <ref name="ipv4_list"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="v6">
- <ref name="ipv6_list"/>
- </attribute>
- </optional>
- <optional>
- <element name="bpki_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- </element>
- </define>
- <define name="parent_elt">
- <element name="parent">
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <optional>
- <attribute name="service_uri">
- <ref name="uri"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="myhandle">
- <ref name="object_handle"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="sia_base">
- <ref name="uri"/>
- </attribute>
- </optional>
- <optional>
- <element name="bpki_cms_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- <optional>
- <element name="bpki_https_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- </element>
- </define>
- <define name="bpki_ca_certificate_elt">
- <element name="bpki_ca_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_crl_elt">
- <element name="bpki_crl">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_repository_certificate_elt">
- <element name="bpki_repository_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_bsc_certificate_elt">
- <element name="bpki_bsc_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_bsc_pkcs10_elt">
- <element name="bpki_bsc_pkcs10">
- <ref name="base64"/>
- </element>
- </define>
-</grammar>
-<!--
- Local Variables:
- indent-tabs-mode: nil
- End:
--->
-'''))
diff --git a/myrpki/schema.rnc b/myrpki/schema.rnc
deleted file mode 100644
index 8ec48195..00000000
--- a/myrpki/schema.rnc
+++ /dev/null
@@ -1,64 +0,0 @@
-# $Id$
-#
-# RelaxNG Schema for MyRPKI XML messages
-#
-# libxml2 (including xmllint) only groks the XML syntax of RelaxNG, so
-# run the compact syntax through trang to get XML syntax.
-
-default namespace = "http://www.hactrn.net/uris/rpki/myrpki/"
-
-base64 = xsd:base64Binary { maxLength="512000" }
-object_handle = xsd:string { maxLength="255" pattern="[\-_A-Za-z0-9]*" }
-pubd_handle = xsd:string { maxLength="255" pattern="[\-_A-Za-z0-9/]*" }
-uri = xsd:anyURI { maxLength="4096" }
-asn_list = xsd:string { maxLength="512000" pattern="[\-,0-9]*" }
-ipv4_list = xsd:string { maxLength="512000" pattern="[\-,0-9/.]*" }
-ipv6_list = xsd:string { maxLength="512000" pattern="[\-,0-9/:a-fA-F]*" }
-
-start = element myrpki {
- attribute version { xsd:positiveInteger { maxInclusive="1" } },
- attribute handle { object_handle },
- attribute repository_handle { pubd_handle },
- roa_request_elt*,
- child_elt*,
- parent_elt*,
- bpki_ca_certificate_elt?,
- bpki_crl_elt?,
- bpki_repository_certificate_elt?,
- bpki_bsc_certificate_elt?,
- bpki_bsc_pkcs10_elt?
-}
-
-roa_request_elt = element roa_request {
- attribute asn { xsd:positiveInteger },
- attribute v4 { ipv4_list },
- attribute v6 { ipv6_list }
-}
-
-child_elt = element child {
- attribute handle { object_handle },
- attribute valid_until { xsd:dateTime { pattern=".*Z" } },
- attribute asns { asn_list }?,
- attribute v4 { ipv4_list }?,
- attribute v6 { ipv6_list }?,
- element bpki_certificate { base64 }?
-}
-
-parent_elt = element parent {
- attribute handle { object_handle },
- attribute service_uri { uri }?,
- attribute myhandle { object_handle }?,
- attribute sia_base { uri }?,
- element bpki_cms_certificate { base64 }?,
- element bpki_https_certificate { base64 }?
-}
-
-bpki_ca_certificate_elt = element bpki_ca_certificate { base64 }
-bpki_crl_elt = element bpki_crl { base64 }
-bpki_repository_certificate_elt = element bpki_repository_certificate { base64 }
-bpki_bsc_certificate_elt = element bpki_bsc_certificate { base64 }
-bpki_bsc_pkcs10_elt = element bpki_bsc_pkcs10 { base64 }
-
-# Local Variables:
-# indent-tabs-mode: nil
-# End:
diff --git a/myrpki/schema.rng b/myrpki/schema.rng
deleted file mode 100644
index 6f37e37a..00000000
--- a/myrpki/schema.rng
+++ /dev/null
@@ -1,197 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- $Id: schema.rnc 2839 2009-10-27 18:53:00Z sra $
-
- RelaxNG Schema for MyRPKI XML messages
-
- libxml2 (including xmllint) only groks the XML syntax of RelaxNG, so
- run the compact syntax through trang to get XML syntax.
--->
-<grammar ns="http://www.hactrn.net/uris/rpki/myrpki/" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
- <define name="base64">
- <data type="base64Binary">
- <param name="maxLength">512000</param>
- </data>
- </define>
- <define name="object_handle">
- <data type="string">
- <param name="maxLength">255</param>
- <param name="pattern">[\-_A-Za-z0-9]*</param>
- </data>
- </define>
- <define name="pubd_handle">
- <data type="string">
- <param name="maxLength">255</param>
- <param name="pattern">[\-_A-Za-z0-9/]*</param>
- </data>
- </define>
- <define name="uri">
- <data type="anyURI">
- <param name="maxLength">4096</param>
- </data>
- </define>
- <define name="asn_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9]*</param>
- </data>
- </define>
- <define name="ipv4_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9/.]*</param>
- </data>
- </define>
- <define name="ipv6_list">
- <data type="string">
- <param name="maxLength">512000</param>
- <param name="pattern">[\-,0-9/:a-fA-F]*</param>
- </data>
- </define>
- <start>
- <element name="myrpki">
- <attribute name="version">
- <data type="positiveInteger">
- <param name="maxInclusive">1</param>
- </data>
- </attribute>
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <attribute name="repository_handle">
- <ref name="pubd_handle"/>
- </attribute>
- <zeroOrMore>
- <ref name="roa_request_elt"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="child_elt"/>
- </zeroOrMore>
- <zeroOrMore>
- <ref name="parent_elt"/>
- </zeroOrMore>
- <optional>
- <ref name="bpki_ca_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_crl_elt"/>
- </optional>
- <optional>
- <ref name="bpki_repository_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_bsc_certificate_elt"/>
- </optional>
- <optional>
- <ref name="bpki_bsc_pkcs10_elt"/>
- </optional>
- </element>
- </start>
- <define name="roa_request_elt">
- <element name="roa_request">
- <attribute name="asn">
- <data type="positiveInteger"/>
- </attribute>
- <attribute name="v4">
- <ref name="ipv4_list"/>
- </attribute>
- <attribute name="v6">
- <ref name="ipv6_list"/>
- </attribute>
- </element>
- </define>
- <define name="child_elt">
- <element name="child">
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <attribute name="valid_until">
- <data type="dateTime">
- <param name="pattern">.*Z</param>
- </data>
- </attribute>
- <optional>
- <attribute name="asns">
- <ref name="asn_list"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="v4">
- <ref name="ipv4_list"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="v6">
- <ref name="ipv6_list"/>
- </attribute>
- </optional>
- <optional>
- <element name="bpki_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- </element>
- </define>
- <define name="parent_elt">
- <element name="parent">
- <attribute name="handle">
- <ref name="object_handle"/>
- </attribute>
- <optional>
- <attribute name="service_uri">
- <ref name="uri"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="myhandle">
- <ref name="object_handle"/>
- </attribute>
- </optional>
- <optional>
- <attribute name="sia_base">
- <ref name="uri"/>
- </attribute>
- </optional>
- <optional>
- <element name="bpki_cms_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- <optional>
- <element name="bpki_https_certificate">
- <ref name="base64"/>
- </element>
- </optional>
- </element>
- </define>
- <define name="bpki_ca_certificate_elt">
- <element name="bpki_ca_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_crl_elt">
- <element name="bpki_crl">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_repository_certificate_elt">
- <element name="bpki_repository_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_bsc_certificate_elt">
- <element name="bpki_bsc_certificate">
- <ref name="base64"/>
- </element>
- </define>
- <define name="bpki_bsc_pkcs10_elt">
- <element name="bpki_bsc_pkcs10">
- <ref name="base64"/>
- </element>
- </define>
-</grammar>
-<!--
- Local Variables:
- indent-tabs-mode: nil
- End:
--->
diff --git a/myrpki/setup-rootd.sh b/myrpki/setup-rootd.sh
deleted file mode 100644
index be7d9368..00000000
--- a/myrpki/setup-rootd.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh -
-#
-# $Id$
-#
-# Copyright (C) 2010 Internet Systems Consortium ("ISC")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# Setting up rootd requires cross-certifying rpkid's resource-holding
-# BPKI trust anchor under the BPKI trust anchor that rootd uses. This
-# script handles that, albiet in a very ugly way.
-#
-# Filenames are wired in, you might need to change these if you've
-# done something more complicated.
-
-export RANDFILE=.OpenSSL.whines.unless.I.set.this
-export BPKI_DIRECTORY=`pwd`/bpki.myirbe
-
-openssl=../openssl/openssl/apps/openssl
-
-$openssl ca -notext -batch -config myrpki.conf \
- -ss_cert bpki.myrpki/ca.cer \
- -out bpki.myirbe/child.cer \
- -extensions ca_x509_ext_xcert0
-
-$openssl x509 -noout -text -in bpki.myirbe/child.cer
diff --git a/myrpki/setup-sql.py b/myrpki/setup-sql.py
deleted file mode 100644
index 638404d9..00000000
--- a/myrpki/setup-sql.py
+++ /dev/null
@@ -1,107 +0,0 @@
-"""
-Automated setup of all the pesky SQL stuff we need. Prompts for MySQL
-root password, pulls other information from myrpki.conf.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-from __future__ import with_statement
-
-import os, getopt, sys, time, rpki.config, getpass, warnings
-
-# Silence warning while loading MySQLdb in Python 2.6, sigh
-if hasattr(warnings, "catch_warnings"):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", DeprecationWarning)
- import MySQLdb
-else:
- import MySQLdb
-
-import _mysql_exceptions
-
-warnings.simplefilter("error", _mysql_exceptions.Warning)
-
-schema_dir = os.path.normpath(os.path.join(sys.path[0], "../rpkid"))
-
-def read_schema(filename):
- """
- Convert an SQL file into a list of SQL statements.
- """
- lines = []
- f = open(filename)
- for line in f:
- line = " ".join(line.split())
- if line and not line.startswith("--"):
- lines.append(line)
- f.close()
- return [statement.strip() for statement in " ".join(lines).rstrip(";").split(";")]
-
-def sql_setup(name):
- """
- Create a new SQL database and construct all its tables.
- """
- database = cfg.get("sql-database", section = name)
- username = cfg.get("sql-username", section = name)
- password = cfg.get("sql-password", section = name)
- schema = read_schema(os.path.join(schema_dir, "%s.sql" % name))
-
- print "Creating database", database
- cur = rootdb.cursor()
- try:
- cur.execute("DROP DATABASE IF EXISTS %s" % database)
- except:
- pass
- cur.execute("CREATE DATABASE %s" % database)
- cur.execute("GRANT ALL ON %s.* TO %s@localhost IDENTIFIED BY %%s" % (database, username), (password,))
- rootdb.commit()
-
- db = MySQLdb.connect(db = database, user = username, passwd = password)
- cur = db.cursor()
- for statement in schema:
- if statement.upper().startswith("DROP TABLE"):
- continue
- if verbose:
- print "+", statement
- cur.execute(statement)
- db.commit()
- db.close()
-
-cfg_file = "myrpki.conf"
-
-verbose = False
-
-opts, argv = getopt.getopt(sys.argv[1:], "c:hv?", ["config=", "help", "verbose"])
-for o, a in opts:
- if o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
- if o in ("-v", "--verbose"):
- verbose = True
- if o in ("-c", "--config"):
- cfg_file = a
-
-cfg = rpki.config.parser(cfg_file, "myirbe")
-
-rootdb = MySQLdb.connect(db = "mysql", user = "root", passwd = getpass.getpass("Please enter your MySQL root password: "))
-
-sql_setup("irdbd")
-sql_setup("rpkid")
-
-if cfg.getboolean("want_pubd", False):
- sql_setup("pubd")
-
-rootdb.close()
diff --git a/myrpki/sql-cleaner.py b/myrpki/sql-cleaner.py
deleted file mode 100644
index 8f5f946a..00000000
--- a/myrpki/sql-cleaner.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-(Re)Initialize SQL tables used by these programs.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import subprocess, ConfigParser
-
-cfg = ConfigParser.RawConfigParser()
-cfg.read("yamltest.conf")
-
-for name in ("rpkid", "irdbd", "pubd"):
-
- try:
- passwd = cfg.get("yamltest", "%s_db_pass" % name)
- except:
- passwd = "fnord"
-
- dbs = [name[:4]]
- dbs.extend("%s%d" % (name[:4], i) for i in xrange(12))
-
- for db in dbs:
- subprocess.check_call(("mysql", "-u", name[:4], "-p" + passwd, db),
- stdin = open("../rpkid/%s.sql" % name))
diff --git a/myrpki/sql-dumper.py b/myrpki/sql-dumper.py
deleted file mode 100644
index 849d0eb1..00000000
--- a/myrpki/sql-dumper.py
+++ /dev/null
@@ -1,35 +0,0 @@
-"""
-Dump backup copies of SQL tables used by these programs.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import subprocess, ConfigParser
-
-cfg = ConfigParser.RawConfigParser()
-cfg.read("yamltest.conf")
-
-for name in ("rpkid", "irdbd", "pubd"):
-
- try:
- passwd = cfg.get("yamltest", "%s_db_pass" % name)
- except:
- passwd = "fnord"
-
- cmd = ["mysqldump", "-u", name[:4], "-p" + passwd, "--databases", name[:4]]
- cmd.extend("%s%d" % (name[:4], i) for i in xrange(12))
- subprocess.check_call(cmd, stdout = open("backup.%s.sql" % name, "w"))
diff --git a/myrpki/start-servers.py b/myrpki/start-servers.py
deleted file mode 100644
index 6bd5493e..00000000
--- a/myrpki/start-servers.py
+++ /dev/null
@@ -1,73 +0,0 @@
-"""
-Start servers, logging to files, looking at config file to figure out
-which servers the user wants started.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-Portions copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-"""
-
-import subprocess, os, getopt, sys, time, rpki.config
-
-rpkid_dir = os.path.normpath(os.path.join(sys.path[0], "../rpkid"))
-
-os.environ["TZ"] = "UTC"
-time.tzset()
-
-cfg_file = "myrpki.conf"
-debug = False
-
-opts, argv = getopt.getopt(sys.argv[1:], "c:dh?", ["config=", "debug" "help"])
-for o, a in opts:
- if o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
- elif o in ("-c", "--config"):
- cfg_file = a
- elif o in ("-d", "--debug"):
- debug = True
-
-names = ["irdbd", "rpkid"]
-
-cfg = rpki.config.parser(cfg_file, "myirbe")
-
-if cfg.getboolean("want_pubd", False):
- names.append("pubd")
-
-if cfg.getboolean("want_rootd", False):
- names.append("rootd")
-
-for name in names:
- cmd = ("python", os.path.join(rpkid_dir, name + ".py"), "-c", cfg_file)
- if debug:
- proc = subprocess.Popen(cmd + ("-d",), stdout = open(name + ".log", "a"), stderr = subprocess.STDOUT)
- else:
- proc = subprocess.Popen(cmd)
- print ("Started %r, pid %s" if proc.poll() is None else "Problem starting %r, pid %s") % (name, proc.pid)
diff --git a/myrpki/test-all.sh b/myrpki/test-all.sh
deleted file mode 100644
index 1dfc3a52..00000000
--- a/myrpki/test-all.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh -
-# $Id$
-
-# Copyright (C) 2009 Internet Systems Consortium ("ISC")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-set -x
-
-export TZ=UTC
-
-screen -X split
-screen -X focus
-
-for i in ../rpkid/testbed.*.yaml
-do
- rm -rf *.xml bpki.myrpki bpki.myirbe test
- python sql-cleaner.py
- screen python yamltest.py $i
- date
- sleep 180
- for j in . . . . . . . . . .
- do
- sleep 30
- date
- ../rcynic/rcynic
- xsltproc --param refresh 0 ../rcynic/rcynic.xsl rcynic.xml | w3m -T text/html -dump
- date
- done
- pstree -ws python | awk '/yamltest/ {system("kill -INT " $2)}'
- sleep 30
- make backup
-done
diff --git a/myrpki/verify-bpki.sh b/myrpki/verify-bpki.sh
deleted file mode 100755
index 9bcf42e6..00000000
--- a/myrpki/verify-bpki.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh -
-# $Id$
-#
-# Copyright (C) 2009 Internet Systems Consortium ("ISC")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-# PERFORMANCE OF THIS SOFTWARE.
-
-# Tests of generated BPKI certificates. Kind of cheesy, but does test
-# the basic stuff.
-
-exec 2>&1
-
-for bpki in bpki.*
-do
- crls=$(find $bpki -name '*.crl')
-
- # Check that CRLs verify properly
- for crl in $crls
- do
- echo -n "$crl: "
- openssl crl -CAfile $bpki/ca.cer -noout -in $crl
- done
-
- # Check that issued certificates verify properly
- cat $bpki/ca.cer $crls | openssl verify -crl_check -CAfile /dev/stdin $(find $bpki -name '*.cer' ! -name 'ca.cer' ! -name '*.cacert.cer')
-
-done
-
-# Check that cross-certified BSC certificates verify properly
-if test -d bpki.myirbe
-then
- cat bpki.myirbe/xcert.*.cer | openssl verify -verbose -CAfile bpki.myirbe/ca.cer -untrusted /dev/stdin bpki.myrpki/bsc.*.cer
-fi
diff --git a/myrpki/xml-parse-test.py b/myrpki/xml-parse-test.py
deleted file mode 100644
index d5f8e007..00000000
--- a/myrpki/xml-parse-test.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""
-Test parser and display tool for myrpki.xml files.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-"""
-
-import lxml.etree, rpki.resource_set, base64, subprocess
-import schema
-
-tree = lxml.etree.parse("myrpki.xml").getroot()
-
-if False:
- print lxml.etree.tostring(tree, pretty_print = True, encoding = "us-ascii", xml_declaration = True)
-
-schema.myrpki.assertValid(tree)
-
-def showitems(x):
- if False:
- for k, v in x.items():
- if v:
- print " ", k, v
-
-def tag(t):
- return "{http://www.hactrn.net/uris/rpki/myrpki/}" + t
-
-print "My handle:", tree.get("handle")
-
-print "Children:"
-for x in tree.getiterator(tag("child")):
- print " ", x
- print " Handle:", x.get("handle")
- print " ASNS: ", rpki.resource_set.resource_set_as(x.get("asns"))
- print " IPv4: ", rpki.resource_set.resource_set_ipv4(x.get("v4"))
- print " Valid: ", x.get("valid_until")
- showitems(x)
-print
-
-print "ROA requests:"
-for x in tree.getiterator(tag("roa_request")):
- print " ", x
- print " ASN: ", x.get("asn")
- print " IPv4:", rpki.resource_set.roa_prefix_set_ipv4(x.get("v4"))
- print " IPv6:", rpki.resource_set.roa_prefix_set_ipv6(x.get("v6"))
- showitems(x)
-print
-
-def showpem(label, b64, kind):
- cmd = ("openssl", kind, "-noout", "-text", "-inform", "DER")
- if kind == "x509":
- cmd += ("-certopt", "no_pubkey,no_sigdump")
- p = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE)
- text = p.communicate(input = base64.b64decode(b64))[0]
- if p.returncode != 0:
- raise subprocess.CalledProcessError(returncode = p.returncode, cmd = cmd)
- print label, text
-
-for x in tree.getiterator(tag("child")):
- cert = x.findtext(tag("bpki_certificate"))
- if cert:
- showpem("Child", cert, "x509")
-
-for x in tree.getiterator(tag("parent")):
- print "Parent URI:", x.get("service_uri")
- cert = x.findtext(tag("bpki_certificate"))
- if cert:
- showpem("Parent", cert, "x509")
-
-ca = tree.findtext(tag("bpki_ca_certificate"))
-if ca:
- showpem("CA", ca, "x509")
-
-bsc = tree.findtext(tag("bpki_bsc_certificate"))
-if bsc:
- showpem("BSC EE", bsc, "x509")
-
-repo = tree.findtext(tag("bpki_repository_certificate"))
-if repo:
- showpem("Repository", repo, "x509")
-
-req = tree.findtext(tag("bpki_bsc_pkcs10"))
-if req:
- showpem("BSC EE", req, "req")
-
-crl = tree.findtext(tag("bpki_crl"))
-if crl:
- showpem("CA", crl, "crl")
diff --git a/myrpki/yamltest.py b/myrpki/yamltest.py
deleted file mode 100644
index c7743661..00000000
--- a/myrpki/yamltest.py
+++ /dev/null
@@ -1,702 +0,0 @@
-"""
-Test framework, using the same YAML test description format as
-testbed.py, but using the myrpki.py and myirbe.py tools to do all the
-back-end work. Reads YAML file, generates .csv and .conf files, runs
-daemons and waits for one of them to exit.
-
-Much of the YAML handling code lifted from testbed.py.
-
-Still to do:
-
-- Implement testebd.py-style delta actions, that is, modify the
- allocation database under control of the YAML file, dump out new
- .csv files, and run myrpki.py and myirbe.py again to feed resulting
- changes into running daemons.
-
-$Id$
-
-Copyright (C) 2009 Internet Systems Consortium ("ISC")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-Portions copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN")
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
-AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
-
-"""
-
-import subprocess, csv, re, os, getopt, sys, base64, yaml, signal, errno, time
-import rpki.resource_set, rpki.sundial, rpki.config, rpki.log, myrpki
-
-# Nasty regular expressions for parsing config files. Sadly, while
-# the Python ConfigParser supports writing config files, it does so in
-# such a limited way that it's easier just to hack this ourselves.
-
-section_regexp = re.compile("\s*\[\s*(.+?)\s*\]\s*$")
-variable_regexp = re.compile("\s*([-a-zA-Z0-9_]+)\s*=\s*(.+?)\s*$")
-
-def cleanpath(*names):
- """
- Construct normalized pathnames.
- """
- return os.path.normpath(os.path.join(*names))
-
-# Pathnames for various things we need
-
-this_dir = os.getcwd()
-test_dir = cleanpath(this_dir, "test")
-rpkid_dir = cleanpath(this_dir, "../rpkid")
-
-prog_myirbe = cleanpath(this_dir, "myirbe.py")
-prog_myrpki = cleanpath(this_dir, "myrpki.py")
-prog_rpkid = cleanpath(rpkid_dir, "rpkid.py")
-prog_irdbd = cleanpath(rpkid_dir, "irdbd.py")
-prog_pubd = cleanpath(rpkid_dir, "pubd.py")
-prog_rootd = cleanpath(rpkid_dir, "rootd.py")
-
-prog_openssl = cleanpath(this_dir, "../openssl/openssl/apps/openssl")
-
-class roa_request(object):
- """
- Representation of a ROA request.
- """
-
- def __init__(self, asn, ipv4, ipv6):
- self.asn = asn
- self.v4 = rpki.resource_set.roa_prefix_set_ipv4("".join(ipv4.split())) if ipv4 else None
- self.v6 = rpki.resource_set.roa_prefix_set_ipv6("".join(ipv6.split())) if ipv6 else None
-
- def __eq__(self, other):
- return self.asn == other.asn and self.v4 == other.v4 and self.v6 == other.v6
-
- def __hash__(self):
- v4 = tuple(self.v4) if self.v4 is not None else None
- v6 = tuple(self.v6) if self.v6 is not None else None
- return self.asn.__hash__() + v4.__hash__() + v6.__hash__()
-
- def __str__(self):
- if self.v4 and self.v6:
- return "%s: %s,%s" % (self.asn, self.v4, self.v6)
- else:
- return "%s: %s" % (self.asn, self.v4 or self.v6)
-
- @classmethod
- def parse(cls, yaml):
- """
- Parse a ROA request from YAML format.
- """
- return cls(yaml.get("asn"), yaml.get("ipv4"), yaml.get("ipv6"))
-
-class allocation_db(list):
- """
- Our allocation database.
- """
-
- def __init__(self, yaml):
- list.__init__(self)
- self.root = allocation(yaml, self)
- assert self.root.is_root()
- if self.root.crl_interval is None:
- self.root.crl_interval = 24 * 60 * 60
- if self.root.regen_margin is None:
- self.root.regen_margin = 24 * 60 * 60
- for a in self:
- if a.sia_base is None:
- if a.runs_pubd():
- base = "rsync://localhost:%d/" % a.rsync_port
- else:
- base = a.parent.sia_base
- a.sia_base = base + a.name + "/"
- if a.base.valid_until is None:
- a.base.valid_until = a.parent.base.valid_until
- if a.crl_interval is None:
- a.crl_interval = a.parent.crl_interval
- if a.regen_margin is None:
- a.regen_margin = a.parent.regen_margin
- i = 0
- for j in xrange(3):
- i = a.sia_base.index("/", i) + 1
- a.client_handle = a.sia_base[i:].rstrip("/")
- self.root.closure()
- self.map = dict((a.name, a) for a in self)
- for a in self:
- if a.is_hosted():
- a.hosted_by = self.map[a.hosted_by]
- a.hosted_by.hosts.append(a)
- assert not a.is_root() and not a.hosted_by.is_hosted()
-
- def dump(self):
- """
- Show contents of allocation database.
- """
- for a in self:
- a.dump()
-
- def make_rootd_openssl(self):
- """
- Factory for a function to run the OpenSSL comand line tool on the
- root node of our allocation database. Could easily be generalized
- if there were a need, but as it happens we only ever need to do
- this for the root node.
- """
- env = { "PATH" : os.environ["PATH"],
- "BPKI_DIRECTORY" : self.root.path("bpki.myirbe"),
- "OPENSSL_CONF" : "/dev/null",
- "RANDFILE" : ".OpenSSL.whines.unless.I.set.this" }
- cwd = self.root.path()
- return lambda *args: subprocess.check_call((prog_openssl,) + args, cwd = cwd, env = env)
-
-class allocation(object):
- """
- One entity in our allocation database. Every entity in the database
- is assumed to hold resources, so needs at least myrpki services.
- Entities that don't have the hosted_by property run their own copies
- of rpkid, irdbd, and pubd, so they also need myirbe services.
- """
-
- parent = None
- crl_interval = None
- regen_margin = None
-
- base_port = 4400
-
- @classmethod
- def allocate_port(cls):
- """
- Allocate a TCP port.
- """
- cls.base_port += 1
- return cls.base_port
-
- base_engine = -1
-
- @classmethod
- def allocate_engine(cls):
- """
- Allocate an engine number, mostly used to construct MySQL database
- names.
- """
- cls.base_engine += 1
- return cls.base_engine
-
- def __init__(self, yaml, db, parent = None):
- db.append(self)
- self.name = yaml["name"]
- self.parent = parent
- self.kids = [allocation(k, db, self) for k in yaml.get("kids", ())]
- valid_until = None
- if "valid_until" in yaml:
- valid_until = rpki.sundial.datetime.fromdatetime(yaml.get("valid_until"))
- if valid_until is None and "valid_for" in yaml:
- valid_until = rpki.sundial.now() + rpki.sundial.timedelta.parse(yaml["valid_for"])
- self.base = rpki.resource_set.resource_bag(
- asn = rpki.resource_set.resource_set_as(yaml.get("asn")),
- v4 = rpki.resource_set.resource_set_ipv4(yaml.get("ipv4")),
- v6 = rpki.resource_set.resource_set_ipv6(yaml.get("ipv6")),
- valid_until = valid_until)
- self.sia_base = yaml.get("sia_base")
- if "crl_interval" in yaml:
- self.crl_interval = rpki.sundial.timedelta.parse(yaml["crl_interval"]).convert_to_seconds()
- if "regen_margin" in yaml:
- self.regen_margin = rpki.sundial.timedelta.parse(yaml["regen_margin"]).convert_to_seconds()
- self.roa_requests = [roa_request.parse(y) for y in yaml.get("roa_request", yaml.get("route_origin", ()))]
- for r in self.roa_requests:
- if r.v4:
- self.base.v4 = self.base.v4.union(r.v4.to_resource_set())
- if r.v6:
- self.base.v6 = self.base.v6.union(r.v6.to_resource_set())
- self.hosted_by = yaml.get("hosted_by")
- self.hosts = []
- if not self.is_hosted():
- self.engine = self.allocate_engine()
- self.rpkid_port = self.allocate_port()
- self.irdbd_port = self.allocate_port()
- if self.runs_pubd():
- self.pubd_port = self.allocate_port()
- self.rsync_port = self.allocate_port()
- if self.is_root():
- self.rootd_port = self.allocate_port()
-
- def closure(self):
- """
- Compute resource closure of this node and its children, to avoid a
- lot of tedious (and error-prone) duplication in the YAML file.
- """
- resources = self.base
- for kid in self.kids:
- resources = resources.union(kid.closure())
- self.resources = resources
- return resources
-
- def dump(self):
- """
- Show content of this allocation node.
- """
- print str(self)
-
- def __str__(self):
- s = self.name + ":\n"
- if self.resources.asn: s += " ASNs: %s\n" % self.resources.asn
- if self.resources.v4: s += " IPv4: %s\n" % self.resources.v4
- if self.resources.v6: s += " IPv6: %s\n" % self.resources.v6
- if self.kids: s += " Kids: %s\n" % ", ".join(k.name for k in self.kids)
- if self.parent: s += " Up: %s\n" % self.parent.name
- if self.sia_base: s += " SIA: %s\n" % self.sia_base
- if self.is_hosted(): s += " Host: %s\n" % self.hosted_by.name
- if self.hosts: s += " Hosts: %s\n" % ", ".join(h.name for h in self.hosts)
- for r in self.roa_requests: s += " ROA: %s\n" % r
- if not self.is_hosted(): s += " IPort: %s\n" % self.irdbd_port
- if self.runs_pubd(): s += " PPort: %s\n" % self.pubd_port
- if not self.is_hosted(): s += " RPort: %s\n" % self.rpkid_port
- if self.runs_pubd(): s += " SPort: %s\n" % self.rsync_port
- if self.is_root(): s += " TPort: %s\n" % self.rootd_port
- return s + " Until: %s\n" % self.resources.valid_until
-
- def is_root(self):
- """
- Is this the root node?
- """
- return self.parent is None
-
- def is_hosted(self):
- """
- Is this entity hosted?
- """
- return self.hosted_by is not None
-
- def runs_pubd(self):
- """
- Does this entity run a pubd?
- """
- return self.is_root() or not (self.is_hosted() or only_one_pubd)
-
- def path(self, *names):
- """
- Construct pathnames in this entity's test directory.
- """
- return cleanpath(test_dir, self.name, *names)
-
- def csvout(self, fn):
- """
- Open and log a CSV output file. We use delimiter and dialect
- settings imported from the myrpki module, so that we automatically
- write CSV files in the right format.
- """
- path = self.path(fn)
- print "Writing", path
- return csv.writer(open(path, "w"), dialect = myrpki.csv_dialect)
-
- def up_down_url(self):
- """
- Construct service URL for this node's parent.
- """
- parent_port = self.parent.hosted_by.rpkid_port if self.parent.is_hosted() else self.parent.rpkid_port
- return "https://localhost:%d/up-down/%s/%s" % (parent_port, self.parent.name, self.name)
-
- def dump_asns(self, fn):
- """
- Write Autonomous System Numbers CSV file.
- """
- f = self.csvout(fn)
- for k in self.kids:
- f.writerows((k.name, a) for a in k.resources.asn)
-
- def dump_children(self, fn):
- """
- Write children CSV file.
- """
- self.csvout(fn).writerows((k.name, k.resources.valid_until, k.path("bpki.myrpki/ca.cer"))
- for k in self.kids)
-
- def dump_parents(self, fn):
- """
- Write parents CSV file.
- """
- if self.is_root():
- self.csvout(fn).writerow(("rootd",
- "https://localhost:%d/" % self.rootd_port,
- self.path("bpki.myirbe/ca.cer"),
- self.path("bpki.myirbe/ca.cer"),
- self.name,
- self.sia_base))
- else:
- parent_host = self.parent.hosted_by if self.parent.is_hosted() else self.parent
- self.csvout(fn).writerow((self.parent.name,
- self.up_down_url(),
- self.parent.path("bpki.myrpki/ca.cer"),
- parent_host.path("bpki.myirbe/ca.cer"),
- self.name,
- self.sia_base))
-
- def dump_prefixes(self, fn):
- """
- Write prefixes CSV file.
- """
- f = self.csvout(fn)
- for k in self.kids:
- f.writerows((k.name, p) for p in (k.resources.v4 + k.resources.v6))
-
- def dump_roas(self, fn):
- """
- Write ROA CSV file.
- """
- group = self.name if self.is_root() else self.parent.name
- f = self.csvout(fn)
- for r in self.roa_requests:
- f.writerows((p, r.asn, group)
- for p in (r.v4 + r.v6 if r.v4 and r.v6 else r.v4 or r.v6 or ()))
-
- def dump_clients(self, fn, db):
- """
- Write pubclients CSV file.
- """
- if self.runs_pubd():
- f = self.csvout(fn)
- f.writerows((s.client_handle, s.path("bpki.myrpki/ca.cer"), s.sia_base)
- for s in (db if only_one_pubd else [self] + self.kids))
-
- def dump_conf(self, fn):
- """
- Write configuration file for OpenSSL and RPKI tools.
- """
-
- host = self.hosted_by if self.is_hosted() else self
-
- r = { ("myrpki", "handle"): self.name }
-
- if not self.is_hosted():
- r["irdbd", "https-url"] = "https://localhost:%d/" % self.irdbd_port
- r["irdbd", "sql-database"] = "irdb%d" % self.engine
- r["myirbe", "irdbd_conf"] = "myrpki.conf"
- r["myirbe", "rpkid_base"] = "https://localhost:%d/" % self.rpkid_port
- r["rpkid", "irdb-url"] = "https://localhost:%d/" % self.irdbd_port
- r["rpkid", "server-host"] = "localhost"
- r["rpkid", "server-port"] = "%d" % self.rpkid_port
- r["rpkid", "sql-database"] = "rpki%d" % self.engine
- r["myirbe", "want_pubd"] = "true" if self.runs_pubd() else "false"
- r["myirbe", "want_rootd"] = "true" if self.is_root() else "false"
- r["irbe_cli", "rpkid-url"] = "https://localhost:%d/left-right" % self.rpkid_port
-
- if self.is_root():
- root_path = "localhost:%d/%s" % (self.rsync_port, self.name)
- r["rootd", "rpki-root-dir"] = "publication/"
- r["rootd", "rpki-base-uri"] = "rsync://%s/" % root_path
- r["rootd", "rpki-root-cert"] = "publication/root.cer"
- r["rootd", "rpki-root-cert-uri"] = "rsync://%s/root.cer" % root_path
- r["rootd", "rpki-subject-cert"] = "%s.cer" % self.name
- r["rootd", "rpki-root-manifest"] = "root.mnf"
- r["rootd", "root_cert_sia"] = r["rootd", "rpki-base-uri"]
- r["rootd", "root_cert_manifest"] = r["rootd", "rpki-base-uri"] + r["rootd", "rpki-root-manifest"]
-
- if self.runs_pubd():
- r["pubd", "server-host"] = "localhost"
- r["pubd", "server-port"] = "%d" % self.pubd_port
- r["pubd", "sql-database"] = "pubd%d" % self.engine
- r["irbe_cli", "pubd-url"] = "https://localhost:%d/control/" % self.pubd_port
-
- s = self
- while not s.runs_pubd():
- s = s.parent
- r["myirbe", "pubd_base"] = "https://localhost:%d/" % s.pubd_port
- r["myirbe", "rsync_base"] = "rsync://localhost:%d/" % s.rsync_port
- r["myrpki", "repository_bpki_certificate"] = s.path("bpki.myirbe/ca.cer")
- r["myrpki", "repository_handle"] = self.client_handle
-
- if self.is_root():
- r["rootd", "server-port"] = "%d" % self.rootd_port
-
- if rpkid_password:
- r["rpkid", "sql-password"] = rpkid_password
-
- if irdbd_password:
- r["irdbd", "sql-password"] = irdbd_password
-
- if pubd_password:
- r["pubd", "sql-password"] = pubd_password
-
- f = open(self.path(fn), "w")
- f.write("# Automatically generated, do not edit\n")
- print "Writing", f.name
-
- section = None
- for line in open("examples/myrpki.conf"):
- if not line.strip() or line.lstrip().startswith("#"):
- continue
- m = section_regexp.match(line)
- if m:
- section = m.group(1)
- if (section is None or
- (self.is_hosted() and section in ("myirbe", "rpkid", "irdbd")) or
- (not self.runs_pubd() and section == "pubd") or
- (not self.is_root() and section in ("rootd", "rootd_x509_extensions"))):
- continue
- m = variable_regexp.match(line) if m is None else None
- variable = m.group(1) if m else None
- if (section, variable) in r:
- line = variable + " = " + r[section, variable] + "\n"
- f.write(line)
-
- f.close()
-
- def dump_rsyncd(self, fn):
- """
- Write rsyncd configuration file.
- """
-
- if self.runs_pubd():
- f = open(self.path(fn), "w")
- print "Writing", f.name
- f.writelines(s + "\n" for s in
- ("# Automatically generated, do not edit",
- "port = %d" % self.rsync_port,
- "address = localhost",
- "[%s]" % self.name,
- "log file = rsyncd.log",
- "read only = yes",
- "use chroot = no",
- "path = %s" % self.path("publication"),
- "comment = RPKI test"))
- f.close()
-
- def run_myirbe(self):
- """
- Run myirbe.py if this entity is not hosted by another engine.
- """
- if not self.is_hosted():
- print "Running myirbe.py for", self.name
- cmd = ["python", prog_myirbe]
- cmd.extend(h.path("myrpki.xml") for h in self.hosts)
- subprocess.check_call(cmd, cwd = self.path())
-
- def run_myrpki(self):
- """
- Run myrpki.py for this entity.
- """
- print "Running myrpki.py for", self.name
- subprocess.check_call(("python", prog_myrpki), cwd = self.path())
-
- def run_python_daemon(self, prog):
- """
- Start a Python daemon and return a subprocess.Popen object
- representing the running daemon.
- """
- basename = os.path.basename(prog)
- p = subprocess.Popen(("python", prog, "-d", "-c", self.path("myrpki.conf")),
- cwd = self.path(),
- stdout = open(self.path(os.path.splitext(basename)[0] + ".log"), "w"),
- stderr = subprocess.STDOUT)
- print "Running %s for %s: pid %d process %r" % (basename, self.name, p.pid, p)
- return p
-
- def run_rpkid(self):
- """
- Run rpkid.
- """
- return self.run_python_daemon(prog_rpkid)
-
- def run_irdbd(self):
- """
- Run irdbd.
- """
- return self.run_python_daemon(prog_irdbd)
-
- def run_pubd(self):
- """
- Run pubd.
- """
- return self.run_python_daemon(prog_pubd)
-
- def run_rootd(self):
- """
- Run rootd.
- """
- return self.run_python_daemon(prog_rootd)
-
- def run_rsyncd(self):
- """
- Run rsyncd.
- """
- p = subprocess.Popen(("rsync", "--daemon", "--no-detach", "--config", "rsyncd.conf"),
- cwd = self.path())
- print "Running rsyncd for %s: pid %d process %r" % (self.name, p.pid, p)
- return p
-
-os.environ["TZ"] = "UTC"
-time.tzset()
-
-cfg_file = "yamltest.conf"
-
-opts, argv = getopt.getopt(sys.argv[1:], "c:h?", ["config=", "help"])
-for o, a in opts:
- if o in ("-h", "--help", "-?"):
- print __doc__
- sys.exit(0)
- if o in ("-c", "--config"):
- cfg_file = a
-
-# We can't usefully process more than one YAMl file at a time, so
-# whine if there's more than one argument left.
-
-if len(argv) > 1:
- raise RuntimeError, "Unexpected arguments %r" % argv
-
-rpki.log.use_syslog = False
-rpki.log.init("yamltest")
-
-yaml_file = argv[0] if argv else "../rpkid/testbed.1.yaml"
-
-# Allow optional config file for this tool to override default
-# passwords: this is mostly so that I can show a complete working
-# example without publishing my own server's passwords.
-
-try:
- cfg = rpki.config.parser(cfg_file, "yamltest")
- rpkid_password = cfg.get("rpkid_db_pass")
- irdbd_password = cfg.get("irdbd_db_pass")
- pubd_password = cfg.get("pubd_db_pass")
- only_one_pubd = cfg.getboolean("only_one_pubd", True)
- prog_openssl = cfg.get("openssl", prog_openssl)
-except:
- rpkid_password = None
- irdbd_password = None
- pubd_password = None
- only_one_pubd = True
-
-# Start clean
-
-for root, dirs, files in os.walk(test_dir, topdown = False):
- for file in files:
- os.unlink(os.path.join(root, file))
- for dir in dirs:
- os.rmdir(os.path.join(root, dir))
-
-# Read first YAML doc in file and process as compact description of
-# test layout and resource allocations. Ignore subsequent YAML docs,
-# they're for testbed.py, not this script.
-
-db = allocation_db(yaml.safe_load_all(open(yaml_file)).next())
-
-# Show what we loaded
-
-db.dump()
-
-# Set up each entity in our test
-
-for d in db:
- os.makedirs(d.path())
- d.dump_asns("asns.csv")
- d.dump_children("children.csv")
- d.dump_parents("parents.csv")
- d.dump_prefixes("prefixes.csv")
- d.dump_roas("roas.csv")
- d.dump_conf("myrpki.conf")
- d.dump_clients("pubclients.csv", db)
- d.dump_rsyncd("rsyncd.conf")
-
-# Do initial myirbe.py run for each hosting entity to set up BPKI
-
-for d in db:
- d.run_myirbe()
-
-# Run myrpki.py several times for each entity. First pass misses
-# stuff that isn't generated until later in first pass. Second pass
-# should pick up everything and reach a stable state. If anything
-# changes during third pass, that's a bug.
-
-for i in xrange(3):
- for d in db:
- d.run_myrpki()
-
-# Set up a few things for rootd
-
-rootd_openssl = db.make_rootd_openssl()
-
-print "Creating rootd BPKI cross-certificate for its child"
-rootd_openssl("ca", "-notext", "-batch",
- "-config", "myrpki.conf",
- "-ss_cert", "bpki.myrpki/ca.cer",
- "-out", "bpki.myirbe/child.cer",
- "-extensions", "ca_x509_ext_xcert0")
-
-os.makedirs(db.root.path("publication"))
-
-print "Creating rootd RPKI root certificate"
-rootd_openssl("x509", "-req", "-sha256", "-outform", "DER",
- "-signkey", "bpki.myirbe/ca.key",
- "-in", "bpki.myirbe/ca.req",
- "-out", "publication/root.cer",
- "-extfile", "myrpki.conf",
- "-extensions", "rootd_x509_extensions")
-
-# At this point we need to start a whole lotta daemons.
-
-progs = []
-
-def all_daemons_running():
- for p in progs:
- if p.poll() is not None:
- return False
- return True
-
-try:
- print "Running daemons"
- progs.append(db.root.run_rootd())
- progs.extend(d.run_irdbd() for d in db if not d.is_hosted())
- progs.extend(d.run_pubd() for d in db if d.runs_pubd())
- progs.extend(d.run_rsyncd() for d in db if d.runs_pubd())
- progs.extend(d.run_rpkid() for d in db if not d.is_hosted())
-
- print "Giving daemons time to start up"
- time.sleep(20)
-
- assert all_daemons_running()
-
- # Run myirbe again for each host, to set up IRDB and RPKI objects.
- # Need to run a second time to push BSC certs out to rpkid. Nothing
- # should happen on the third pass. Oops, when hosting we need to
- # run myrpki between myirbe passes, since only the hosted entity can
- # issue the BSC, etc.
-
- for i in xrange(3):
- for d in db:
- d.run_myrpki()
- for d in db:
- d.run_myirbe()
-
- print "Done initializing daemons"
-
- # Wait until something terminates.
-
- signal.signal(signal.SIGCHLD, lambda *dont_care: None)
- if all_daemons_running():
- signal.pause()
-
-finally:
-
- # Shut everything down.
-
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- for p in progs:
- if p.poll() is None:
- os.kill(p.pid, signal.SIGTERM)
- print "Program pid %d %r returned %d" % (p.pid, p, p.wait())