Merge branch 'master' into google-ct
This commit is contained in:
commit
b19ea71dbf
|
|
@ -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
|
||||
|
|
|
|||
47
README.md
47
README.md
|
|
@ -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.
|
||||
|
||||
|
||||
[](https://travis-ci.org/letsencrypt/boulder)
|
||||
[](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
|
||||
----
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
7
test.sh
7
test.sh
|
|
@ -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.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue