Merge branch 'master' into google-ct

This commit is contained in:
Jeff Hodges 2015-12-04 16:17:27 -08:00
commit b19ea71dbf
11 changed files with 90 additions and 96 deletions

View File

@ -39,7 +39,7 @@ branches:
- /^test-.*$/
before_install:
- source test/travis-before-install.sh
- travis_retry test/travis-before-install.sh
# Override default Travis install command to prevent it from adding
# Godeps/_workspace to GOPATH. When that happens, it hides failures that should

View File

@ -3,7 +3,6 @@ Boulder - An ACME CA
This is an initial implementation of an ACME-based CA. The [ACME protocol](https://github.com/letsencrypt/acme-spec/) allows the CA to automatically verify that an applicant for a certificate actually controls an identifier, and allows domain holders to issue and revoke certificates for their domains.
[![Build Status](https://travis-ci.org/letsencrypt/boulder.svg)](https://travis-ci.org/letsencrypt/boulder)
[![Coverage Status](https://coveralls.io/repos/letsencrypt/boulder/badge.svg)](https://coveralls.io/r/letsencrypt/boulder)
@ -54,29 +53,18 @@ or
(On OS X, using port, you will have to add `CGO_CFLAGS="-I/opt/local/include" CGO_LDFLAGS="-L/opt/local/lib"` to your environment or `go` invocations.)
Resolve Go-dependencies:
Resolve Go-dependencies, set up a database and RabbitMQ:
> go get bitbucket.org/liamstask/goose/cmd/goose
> go get github.com/jsha/listenbuddy
> go get github.com/letsencrypt/boulder/ # Ignore errors about no buildable files
> go get -u github.com/golang/lint/golint
> ./test/setup.sh
Set up a database:
> cd $GOPATH/src/github.com/letsencrypt/boulder
> ./test/create_db.sh
Set up RabbitMQ:
> go run cmd/rabbitmq-setup/main.go -server amqp://localhost
**Note**: `create_db.sh` uses the root MariaDB user with the default
password, so if you have disabled that account or changed the password
you may have to adjust the file or recreate the commands.
**Note**: `setup.sh` calls `create_db.sh`, which uses the root MariaDB
user with the default password, so if you have disabled that account
or changed the password you may have to adjust the file or recreate the commands.
Start each boulder component with test configs (Ctrl-C kills all):
> ./start.py
Run tests:
> ./test.sh
@ -108,27 +96,21 @@ client <-checks-> VA ---+
```
In Boulder, these components are represented by Go interfaces. This allows us to have two operational modes: Consolidated and distributed. In consolidated mode, the objects representing the different components interact directly, through function calls. In distributed mode, each component runs in a separate process (possibly on a separate machine), and sees the other components' methods by way of a messaging layer.
Internally, the logic of the system is based around two types of objects, authorizations and certificates, mapping directly to the resources of the same name in ACME.
Internally, the logic of the system is based around four types of objects: registrations, authorizations, challenges, and certificates, mapping directly to the resources of the same name in ACME.
Requests from ACME clients result in new objects and changes to objects. The Storage Authority maintains persistent copies of the current set of objects.
Objects are also passed from one component to another on change events. For example, when a client provides a successful response to a validation challenge, it results in a change to the corresponding validation object. The Validation Authority forward the new validation object to the Storage Authority for storage, and to the Registration Authority for any updates to a related Authorization object.
Objects are also passed from one component to another on change events. For example, when a client provides a successful response to a validation challenge, it results in a change to the corresponding validation object. The Validation Authority forwards the new validation object to the Storage Authority for storage, and to the Registration Authority for any updates to a related Authorization object.
Boulder supports distributed operation using AMQP as a message bus (e.g., via RabbitMQ). For components that you want to be remote, it is necessary to instantiate a "client" and "server" for that component. The client implements the component's Go interface, while the server has the actual logic for the component. More details in `amqp-rpc.go`.
Boulder uses AMQP as a message bus. For components that you want to be remote, it is necessary to instantiate a "client" and "server" for that component. The client implements the component's Go interface, while the server has the actual logic for the component. More details in `amqp-rpc.go`.
The full details of how the various ACME operations happen in Boulder are laid out in [DESIGN.md](https://github.com/letsencrypt/boulder/blob/master/DESIGN.md)
Dependencies
------------
All Go dependencies are vendorized under the Godeps directory,
both to [make dependency management
easier](https://groups.google.com/forum/m/#!topic/golang-dev/nMWoEAG55v8)
and to [avoid insecure fallback in go
get](https://github.com/golang/go/issues/9637).
to [make dependency management easier](https://groups.google.com/forum/m/#!topic/golang-dev/nMWoEAG55v8).
Local development also requires a RabbitMQ installation and MariaDB
10 installation (see above). MariaDB should be run on port 3306 for the
@ -137,10 +119,10 @@ default integration tests.
To update the Go dependencies:
```
# Disable insecure fallback by blocking port 80.
sudo /sbin/iptables -A OUTPUT -p tcp --dport 80 -j DROP
# Fetch godep
go get -u https://github.com/tools/godep
# Check out the currently vendorized version of each dependency.
godep restore
# Update to the latest version of a dependency. Alternately you can cd to the
# directory under GOPATH and check out a specific revision. Here's an example
# using cfssl:
@ -152,11 +134,8 @@ godep update github.com/cloudflare/cfssl/...
godep save -r ./...
git add Godeps
git commit
# Assuming you had no other iptables rules, re-enable port 80.
sudo iptables -D OUTPUT 1
```
TODO
----

View File

@ -25,14 +25,15 @@ func init() {
// Constants for AMQP
const (
monitorQueueName = "Monitor"
amqpExchange = "boulder"
amqpExchangeType = "topic"
amqpInternal = false
amqpDurable = false
amqpDeleteUnused = false
amqpExclusive = false
amqpNoWait = false
monitorQueueName = "Monitor"
amqpExchange = "boulder"
amqpExchangeType = "topic"
amqpInternal = false
amqpExchangeDurable = true
amqpQueueDurable = false
amqpDeleteUnused = false
amqpExclusive = false
amqpNoWait = false
)
func main() {
@ -45,7 +46,7 @@ func main() {
err = ch.ExchangeDeclare(
amqpExchange,
amqpExchangeType,
amqpDurable,
amqpExchangeDurable,
amqpDeleteUnused,
amqpInternal,
amqpNoWait,
@ -54,7 +55,7 @@ func main() {
_, err = ch.QueueDeclare(
monitorQueueName,
amqpDurable,
amqpQueueDurable,
amqpDeleteUnused,
amqpExclusive,
amqpNoWait,

View File

@ -354,8 +354,11 @@ func (u *AcmeURL) UnmarshalJSON(data []byte) error {
}
uu, err := url.Parse(str)
if err != nil {
return err
}
*u = AcmeURL(*uu)
return err
return nil
}
// VerifyCSR verifies that a Certificate Signature Request is well-formed.

View File

@ -120,3 +120,11 @@ func TestUniqueLowerNames(t *testing.T) {
sort.Strings(u)
test.AssertDeepEquals(t, []string{"bar.com", "baz.com", "foobar.com"}, u)
}
func TestUnmarshalAcmeURL(t *testing.T) {
var u AcmeURL
err := u.UnmarshalJSON([]byte(`":"`))
if err == nil {
t.Errorf("Expected error parsing ':', but got nil err.")
}
}

View File

@ -216,6 +216,9 @@ func (ra *RegistrationAuthorityImpl) validateContacts(contacts []*core.AcmeURL)
}
for _, contact := range contacts {
if contact == nil {
return core.MalformedRequestError("Invalid contact")
}
switch contact.Scheme {
case "tel":
continue

View File

@ -304,6 +304,9 @@ func TestValidateContacts(t *testing.T) {
err = ra.validateContacts([]*core.AcmeURL{ansible})
test.AssertError(t, err, "Unknown scheme")
err = ra.validateContacts([]*core.AcmeURL{nil})
test.AssertError(t, err, "Nil AcmeURL")
}
func TestValidateEmail(t *testing.T) {

View File

@ -366,7 +366,7 @@ func makeAmqpChannel(conf *cmd.AMQPConfig) (*amqp.Channel, error) {
func (rpc *AmqpRPCServer) processMessage(msg amqp.Delivery) {
// XXX-JWS: jws.Verify(body)
cb, present := rpc.dispatchTable[msg.Type]
rpc.log.Info(fmt.Sprintf(" [s<][%s][%s] received %s(%s) [%s]", rpc.serverQueue, msg.ReplyTo, msg.Type, safeDER(msg.Body), msg.CorrelationId))
rpc.log.Debug(fmt.Sprintf(" [s<][%s][%s] received %s(%s) [%s]", rpc.serverQueue, msg.ReplyTo, msg.Type, safeDER(msg.Body), msg.CorrelationId))
if !present {
// AUDIT[ Misrouted Messages ] f523f21f-12d2-4c31-b2eb-ee4b7d96d60e
rpc.log.Audit(fmt.Sprintf(" [s<][%s][%s] Misrouted message: %s - %s - %s", rpc.serverQueue, msg.ReplyTo, msg.Type, safeDER(msg.Body), msg.CorrelationId))

View File

@ -217,13 +217,6 @@ if [[ "$RUN" =~ "migrations" ]] ; then
end_context #"migrations"
fi
#
# Prepare the database for unittests and integration tests
#
if [[ "${TRAVIS}" == "true" ]] ; then
./test/create_db.sh || die "unable to create the boulder database with test/create_db.sh"
fi
#
# Unit Tests.
#

26
test/setup.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
#
# Fetch dependencies of Boulderthat are necessary for development or testing,
# and configure database and RabbitMQ.
#
go get \
golang.org/x/tools/cmd/vet \
golang.org/x/tools/cmd/cover \
github.com/golang/lint/golint \
github.com/mattn/goveralls \
github.com/modocache/gover \
github.com/jcjones/github-pr-status \
github.com/jsha/listenbuddy &
(wget https://github.com/jsha/boulder-tools/raw/master/goose.gz &&
mkdir -p $GOPATH/bin &&
zcat goose.gz > $GOPATH/bin/goose &&
chmod +x $GOPATH/bin/goose &&
./test/create_db.sh) &
# Set up rabbitmq exchange and activity monitor queue
go run cmd/rabbitmq-setup/main.go -server amqp://localhost &
# Wait for all the background commands to finish.
wait

View File

@ -1,50 +1,28 @@
#!/bin/bash
set -o xtrace
if [ "${TRAVIS}" == "true" ]; then
# Boulder consists of multiple Go packages, which
# refer to each other by their absolute GitHub path,
# e.g. github.com/letsencrypt/boulder/analysis. That means, by default, if
# someone forks the repo, Travis won't pass on their own repo. To fix that,
# we add a symlink.
mkdir -p $TRAVIS_BUILD_DIR $GOPATH/src/github.com/letsencrypt
if [ ! -d $GOPATH/src/github.com/letsencrypt/boulder ] ; then
ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/letsencrypt/boulder
fi
# Travis does shallow clones, so there is no master branch present.
# But test-no-outdated-migrations.sh needs to check diffs against master.
# Fetch just the master branch from origin.
( git fetch origin master
git branch master FETCH_HEAD ) &
# Github-PR-Status secret
if [ -n "$encrypted_53b2630f0fb4_key" ]; then
openssl aes-256-cbc \
-K $encrypted_53b2630f0fb4_key -iv $encrypted_53b2630f0fb4_iv \
-in test/github-secret.json.enc -out /tmp/github-secret.json -d
fi
else
alias travis_retry=""
# Boulder consists of multiple Go packages, which
# refer to each other by their absolute GitHub path,
# e.g. github.com/letsencrypt/boulder/analysis. That means, by default, if
# someone forks the repo, Travis won't pass on their own repo. To fix that,
# we add a symlink.
mkdir -p $TRAVIS_BUILD_DIR $GOPATH/src/github.com/letsencrypt
if [ ! -d $GOPATH/src/github.com/letsencrypt/boulder ] ; then
ln -s $TRAVIS_BUILD_DIR $GOPATH/src/github.com/letsencrypt/boulder
fi
travis_retry go get \
golang.org/x/tools/cmd/vet \
golang.org/x/tools/cmd/cover \
github.com/golang/lint/golint \
github.com/mattn/goveralls \
github.com/modocache/gover \
github.com/jcjones/github-pr-status \
github.com/jsha/listenbuddy &
# Travis does shallow clones, so there is no master branch present.
# But test-no-outdated-migrations.sh needs to check diffs against master.
# Fetch just the master branch from origin.
( git fetch origin master
git branch master FETCH_HEAD ) &
# Github-PR-Status secret
if [ -n "$encrypted_53b2630f0fb4_key" ]; then
openssl aes-256-cbc \
-K $encrypted_53b2630f0fb4_key -iv $encrypted_53b2630f0fb4_iv \
-in test/github-secret.json.enc -out /tmp/github-secret.json -d
fi
(wget https://github.com/jsha/boulder-tools/raw/master/goose.gz &&
mkdir -p $GOPATH/bin &&
zcat goose.gz > $GOPATH/bin/goose &&
chmod +x $GOPATH/bin/goose) &
# Set up rabbitmq exchange and activity monitor queue
go run cmd/rabbitmq-setup/main.go -server amqp://localhost &
# Wait for all the background commands to finish.
wait
./test/setup.sh
set +o xtrace