mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
Fix(db): needs encryption migration function fixed EE-2414 (#6494)
* fix(db) NeedsEncryptionMigration EE-2414 * fix for case where we started encrypted and restore unencrypted. We don't want to have two databases * fix(db): handle decryption error EE-2466 Co-authored-by: Matt Hook <hookenz@gmail.com> Co-authored-by: andres-portainer <andres-portainer@users.noreply.github.com>
This commit is contained in:
parent
ad7f87122d
commit
a8d3cda3fa
7 changed files with 250 additions and 60 deletions
|
@ -2,6 +2,7 @@ package boltdb
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -10,7 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
"github.com/portainer/portainer/api/dataservices/errors"
|
||||
dserrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -19,6 +20,11 @@ const (
|
|||
EncryptedDatabaseFileName = "portainer.edb"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrHaveEncryptedAndUnencrypted = errors.New("Portainer has detected both an encrypted and un-encrypted database and cannot start. Only one database should exist")
|
||||
ErrHaveEncryptedWithNoKey = errors.New("The portainer database is encrypted, but no secret was loaded")
|
||||
)
|
||||
|
||||
type DbConnection struct {
|
||||
Path string
|
||||
MaxBatchSize int
|
||||
|
@ -64,19 +70,51 @@ func (connection *DbConnection) IsEncryptedStore() bool {
|
|||
|
||||
// NeedsEncryptionMigration returns true if database encryption is enabled and
|
||||
// we have an un-encrypted DB that requires migration to an encrypted DB
|
||||
func (connection *DbConnection) NeedsEncryptionMigration() bool {
|
||||
if connection.EncryptionKey != nil {
|
||||
dbFile := path.Join(connection.Path, DatabaseFileName)
|
||||
if _, err := os.Stat(dbFile); err == nil {
|
||||
return true
|
||||
}
|
||||
func (connection *DbConnection) NeedsEncryptionMigration() (bool, error) {
|
||||
|
||||
// This is an existing encrypted store or a new store.
|
||||
// A new store will open encrypted from the outset
|
||||
// Cases: Note, we need to check both portainer.db and portainer.edb
|
||||
// to determine if it's a new store. We only need to differentiate between cases 2,3 and 5
|
||||
|
||||
// 1) portainer.edb + key => False
|
||||
// 2) portainer.edb + no key => ERROR Fatal!
|
||||
// 3) portainer.db + key => True (needs migration)
|
||||
// 4) portainer.db + no key => False
|
||||
// 5) NoDB (new) + key => False
|
||||
// 6) NoDB (new) + no key => False
|
||||
// 7) portainer.db & portainer.edb => ERROR Fatal!
|
||||
|
||||
// If we have a loaded encryption key, always set encrypted
|
||||
if connection.EncryptionKey != nil {
|
||||
connection.SetEncrypted(true)
|
||||
}
|
||||
|
||||
return false
|
||||
// Check for portainer.db
|
||||
dbFile := path.Join(connection.Path, DatabaseFileName)
|
||||
_, err := os.Stat(dbFile)
|
||||
haveDbFile := err == nil
|
||||
|
||||
// Check for portainer.edb
|
||||
edbFile := path.Join(connection.Path, EncryptedDatabaseFileName)
|
||||
_, err = os.Stat(edbFile)
|
||||
haveEdbFile := err == nil
|
||||
|
||||
if haveDbFile && haveEdbFile {
|
||||
// 7 - encrypted and unencrypted db?
|
||||
return false, ErrHaveEncryptedAndUnencrypted
|
||||
}
|
||||
|
||||
if haveDbFile && connection.EncryptionKey != nil {
|
||||
// 3 - needs migration
|
||||
return true, nil
|
||||
}
|
||||
|
||||
if haveEdbFile && connection.EncryptionKey == nil {
|
||||
// 2 - encrypted db, but no key?
|
||||
return false, ErrHaveEncryptedWithNoKey
|
||||
}
|
||||
|
||||
// 1, 4, 5, 6
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Open opens and initializes the BoltDB database.
|
||||
|
@ -159,7 +197,7 @@ func (connection *DbConnection) GetObject(bucketName string, key []byte, object
|
|||
|
||||
value := bucket.Get(key)
|
||||
if value == nil {
|
||||
return errors.ErrObjectNotFound
|
||||
return dserrors.ErrObjectNotFound
|
||||
}
|
||||
|
||||
data = make([]byte, len(value))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue