Skip to content

Commit

Permalink
config: add validation for storage.encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
lucab committed Feb 12, 2018
1 parent dbccedd commit 7f708b5
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 0 deletions.
101 changes: 101 additions & 0 deletions config/types/encryption.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
"errors"
"fmt"

"github.com/coreos/ignition/config/validate/report"
)

const (
// csDevicesMax is the maximum number of Cryptsetup devices that can be
// created at once. It is an arbitrary sane number for input validation,
// it can be bumped if required.
csDevicesMax = 1024
// csKeyslotsMax is the maximux number of keyslots allowed per Cryptsetup device
csKeyslotsMax = 1 // TODO(lucab): this could be expanded to 8
)

var (
// ErrNoKeyslots is reported when 0 keyslots are specified
ErrNoKeyslots = errors.New("no keyslots specified")
// ErrNoKeyslotConfig is reported when a keyslot has no configured source
ErrNoKeyslotConfig = errors.New("keyslot is missing provider configuration")
// ErrTooManyKeyslotConfigs is reported when a keyslot has too many configured sources
ErrTooManyKeyslotConfigs = errors.New("keyslot has multiple provider configurations")
// ErrNoDevmapperName is reported when no device-mapper name is specified
ErrNoDevmapperName = errors.New("missing device-mapper name")
// ErrNoDevicePath is reported when no device path is specified
ErrNoDevicePath = errors.New("missing device path")
// ErrTooManyDevices is reported when too many devices are specified
ErrTooManyDevices = fmt.Errorf("too many devices specified, at most %d allowed", csDevicesMax)
// ErrTooManyKeyslots is reported when too many keyslots are specified
ErrTooManyKeyslots = fmt.Errorf("too many keyslots specified, at most %d allowed", csKeyslotsMax)
)

// Validate ensures a Cryptsetup entry is sane
//
// It fulfills validate.validator interface.
func (e Encryption) Validate() report.Report {
r := report.Report{}

if e.Name == "" {
r.Add(report.Entry{
Message: ErrNoDevmapperName.Error(),
Kind: report.EntryError,
})
}
if e.Device == "" {
r.Add(report.Entry{
Message: ErrNoDevicePath.Error(),
Kind: report.EntryError,
})
}
if len(e.KeySlots) == 0 {
r.Add(report.Entry{
Message: ErrNoKeyslots.Error(),
Kind: report.EntryError,
})
}
if len(e.KeySlots) > csKeyslotsMax {
r.Add(report.Entry{
Message: ErrTooManyKeyslots.Error(),
Kind: report.EntryError,
})
}

for _, ks := range e.KeySlots {
ksConfigured := 0
if ks.Content != nil {
ksConfigured++
}
// TODO(lucab): validate new providers here.
if ksConfigured == 0 {
r.Add(report.Entry{
Message: ErrNoKeyslotConfig.Error(),
Kind: report.EntryError,
})
} else if ksConfigured > 1 {
r.Add(report.Entry{
Message: ErrTooManyKeyslotConfigs.Error(),
Kind: report.EntryError,
})
}
}

return r
}
55 changes: 55 additions & 0 deletions config/types/encryption_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2017 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
"reflect"
"testing"

"github.com/coreos/ignition/config/validate/report"
)

func TestCryptsetupValidate(t *testing.T) {
simpleSlots := []Keyslot{
{
Content: &Content{Source: "https://localhost/key.txt"},
},
}

tests := []struct {
in Encryption
out error
}{
{
in: Encryption{Name: "foo", Device: "/dev/bar", KeySlots: simpleSlots},
out: nil,
},
{
in: Encryption{Name: "", Device: "/dev/bar", KeySlots: simpleSlots},
out: ErrNoDevmapperName,
},
{
in: Encryption{Name: "foo", Device: "", KeySlots: simpleSlots},
out: ErrNoDevicePath,
},
}

for i, tt := range tests {
err := tt.in.Validate()
if !reflect.DeepEqual(report.ReportFromError(tt.out, report.EntryError), err) {
t.Errorf("#%d: bad error: want %v, got %v", i, tt.out, err)
}
}
}

0 comments on commit 7f708b5

Please sign in to comment.