func TestRethinkBootstrapSetsUsernamePassword(t *testing.T) { adminSession, source := rethinkSessionSetup(t) dbname, username, password := "******", "testuser", "testpassword" otherDB, otherUser, otherPass := "******", "otheruser", "otherpassword" // create a separate user with access to a different DB require.NoError(t, rethinkdb.SetupDB(adminSession, otherDB, nil)) defer gorethink.DBDrop(otherDB).Exec(adminSession) require.NoError(t, rethinkdb.CreateAndGrantDBUser(adminSession, otherDB, otherUser, otherPass)) // Bootstrap s := NewRethinkDBKeyStore(dbname, username, password, constRetriever, "ignored", adminSession) require.NoError(t, s.Bootstrap()) defer gorethink.DBDrop(dbname).Exec(adminSession) // A user with an invalid password cannot connect to rethink DB at all _, err := rethinkdb.UserConnection(tlsOpts, source, username, "wrongpass") require.Error(t, err) // the other user cannot access rethink, causing health checks to fail userSession, err := rethinkdb.UserConnection(tlsOpts, source, otherUser, otherPass) require.NoError(t, err) s = NewRethinkDBKeyStore(dbname, otherUser, otherPass, constRetriever, "ignored", userSession) _, _, err = s.GetPrivateKey("nonexistent") require.Error(t, err) require.IsType(t, gorethink.RQLRuntimeError{}, err) key := s.GetKey("nonexistent") require.Nil(t, key) require.Error(t, s.CheckHealth()) // our user can access the DB though userSession, err = rethinkdb.UserConnection(tlsOpts, source, username, password) require.NoError(t, err) s = NewRethinkDBKeyStore(dbname, username, password, constRetriever, "ignored", userSession) _, _, err = s.GetPrivateKey("nonexistent") require.Error(t, err) require.IsType(t, trustmanager.ErrKeyNotFound{}, err) require.NoError(t, s.CheckHealth()) }
func TestRethinkBootstrapSetsUsernamePassword(t *testing.T) { adminSession, source := rethinkSessionSetup(t) dbname, username, password := "******", "testuser", "testpassword" otherDB, otherUser, otherPass := "******", "otheruser", "otherpassword" // create a separate user with access to a different DB require.NoError(t, rethinkdb.SetupDB(adminSession, otherDB, nil)) defer gorethink.DBDrop(otherDB).Exec(adminSession) require.NoError(t, rethinkdb.CreateAndGrantDBUser(adminSession, otherDB, otherUser, otherPass)) // Bootstrap s := NewRethinkDBStorage(dbname, username, password, adminSession) require.NoError(t, s.Bootstrap()) defer gorethink.DBDrop(dbname).Exec(adminSession) // A user with an invalid password cannot connect to rethink DB at all _, err := rethinkdb.UserConnection(tlsOpts, source, username, "wrongpass") require.Error(t, err) // the other user cannot access rethink, causing health checks to fail userSession, err := rethinkdb.UserConnection(tlsOpts, source, otherUser, otherPass) require.NoError(t, err) s = NewRethinkDBStorage(dbname, otherUser, otherPass, userSession) _, _, err = s.GetCurrent("gun", data.CanonicalRootRole) require.Error(t, err) require.IsType(t, gorethink.RQLRuntimeError{}, err) require.Error(t, s.CheckHealth()) // our user can access the DB though userSession, err = rethinkdb.UserConnection(tlsOpts, source, username, password) require.NoError(t, err) s = NewRethinkDBStorage(dbname, username, password, userSession) _, _, err = s.GetCurrent("gun", data.CanonicalRootRole) require.Error(t, err) require.IsType(t, ErrNotFound{}, err) require.NoError(t, s.CheckHealth()) }
// parses the configuration and returns a backing store for the TUF files func getStore(configuration *viper.Viper, hRegister healthRegister) ( storage.MetaStore, error) { var store storage.MetaStore backend := configuration.GetString("storage.backend") logrus.Infof("Using %s backend", backend) switch backend { case notary.MemoryBackend: return storage.NewMemStorage(), nil case notary.MySQLBackend, notary.SQLiteBackend: storeConfig, err := utils.ParseSQLStorage(configuration) if err != nil { return nil, err } s, err := storage.NewSQLStorage(storeConfig.Backend, storeConfig.Source) if err != nil { return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error()) } store = *storage.NewTUFMetaStorage(s) hRegister("DB operational", time.Minute, s.CheckHealth) case notary.RethinkDBBackend: var sess *gorethink.Session storeConfig, err := utils.ParseRethinkDBStorage(configuration) if err != nil { return nil, err } tlsOpts := tlsconfig.Options{ CAFile: storeConfig.CA, CertFile: storeConfig.Cert, KeyFile: storeConfig.Key, } if doBootstrap { sess, err = rethinkdb.AdminConnection(tlsOpts, storeConfig.Source) } else { sess, err = rethinkdb.UserConnection(tlsOpts, storeConfig.Source, storeConfig.Username, storeConfig.Password) } if err != nil { return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error()) } s := storage.NewRethinkDBStorage(storeConfig.DBName, storeConfig.Username, storeConfig.Password, sess) store = *storage.NewTUFMetaStorage(s) hRegister("DB operational", time.Minute, s.CheckHealth) default: return nil, fmt.Errorf("%s is not a supported storage backend", backend) } return store, nil }
// Reads the configuration file for storage setup, and sets up the cryptoservice // mapping func setUpCryptoservices(configuration *viper.Viper, allowedBackends []string, doBootstrap bool) ( signer.CryptoServiceIndex, error) { backend := configuration.GetString("storage.backend") if !tufutils.StrSliceContains(allowedBackends, backend) { return nil, fmt.Errorf("%s is not an allowed backend, must be one of: %s", backend, allowedBackends) } var keyService signed.CryptoService switch backend { case notary.MemoryBackend: keyService = cryptoservice.NewCryptoService(trustmanager.NewKeyMemoryStore( passphrase.ConstantRetriever("memory-db-ignore"))) case notary.RethinkDBBackend: var sess *gorethink.Session storeConfig, err := utils.ParseRethinkDBStorage(configuration) if err != nil { return nil, err } defaultAlias, err := getDefaultAlias(configuration) if err != nil { return nil, err } tlsOpts := tlsconfig.Options{ CAFile: storeConfig.CA, CertFile: storeConfig.Cert, KeyFile: storeConfig.Key, } if doBootstrap { sess, err = rethinkdb.AdminConnection(tlsOpts, storeConfig.Source) } else { sess, err = rethinkdb.UserConnection(tlsOpts, storeConfig.Source, storeConfig.Username, storeConfig.Password) } if err != nil { return nil, fmt.Errorf("Error starting %s driver: %s", backend, err.Error()) } s := keydbstore.NewRethinkDBKeyStore(storeConfig.DBName, storeConfig.Username, storeConfig.Password, passphraseRetriever, defaultAlias, sess) health.RegisterPeriodicFunc("DB operational", time.Minute, s.CheckHealth) if doBootstrap { keyService = s } else { keyService = keydbstore.NewCachedKeyService(s) } case notary.MySQLBackend, notary.SQLiteBackend, notary.PostgresBackend: storeConfig, err := utils.ParseSQLStorage(configuration) if err != nil { return nil, err } defaultAlias, err := getDefaultAlias(configuration) if err != nil { return nil, err } dbStore, err := keydbstore.NewSQLKeyDBStore( passphraseRetriever, defaultAlias, storeConfig.Backend, storeConfig.Source) if err != nil { return nil, fmt.Errorf("failed to create a new keydbstore: %v", err) } health.RegisterPeriodicFunc( "DB operational", time.Minute, dbStore.HealthCheck) keyService = keydbstore.NewCachedKeyService(dbStore) } if doBootstrap { err := bootstrap(keyService) if err != nil { logrus.Fatal(err.Error()) } os.Exit(0) } cryptoServices := make(signer.CryptoServiceIndex) cryptoServices[data.ED25519Key] = keyService cryptoServices[data.ECDSAKey] = keyService return cryptoServices, nil }