diff --git a/jslib b/jslib index 2aa71f98..28301214 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 2aa71f98a1f623470b3bd71306e0ef8a1ba97758 +Subproject commit 2830121471fb7c6dca6de934c5f28520294fbffb diff --git a/src/bwdc.ts b/src/bwdc.ts index 27fe3bf3..b7646d91 100644 --- a/src/bwdc.ts +++ b/src/bwdc.ts @@ -25,6 +25,8 @@ import { NoopMessagingService } from 'jslib/services/noopMessaging.service'; import { TokenService } from 'jslib/services/token.service'; import { UserService } from 'jslib/services/user.service'; +import { StorageService as StorageServiceAbstraction } from 'jslib/abstractions/storage.service'; + import { Program } from './program'; // tslint:disable-next-line @@ -35,7 +37,7 @@ export class Main { logService: ConsoleLogService; messagingService: NoopMessagingService; storageService: LowdbStorageService; - secureStorageService: KeytarSecureStorageService; + secureStorageService: StorageServiceAbstraction; i18nService: I18nService; platformUtilsService: CliPlatformUtilsService; constantsService: ConstantsService; @@ -70,13 +72,15 @@ export class Main { this.dataFilePath = path.join(process.env.HOME, '.config/' + applicationName); } + const plaintextSecrets = process.env.BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS === 'true'; this.i18nService = new I18nService('en', './locales'); this.platformUtilsService = new CliPlatformUtilsService('connector', packageJson); this.logService = new ConsoleLogService(this.platformUtilsService.isDev(), - (level) => process.env.BWCLI_DEBUG !== 'true' && level <= LogLevelType.Info); + (level) => process.env.BITWARDENCLI_CONNECTOR_DEBUG !== 'true' && level <= LogLevelType.Info); this.cryptoFunctionService = new NodeCryptoFunctionService(); this.storageService = new LowdbStorageService(null, this.dataFilePath, true); - this.secureStorageService = new KeytarSecureStorageService(applicationName); + this.secureStorageService = plaintextSecrets ? + this.storageService : new KeytarSecureStorageService(applicationName); this.cryptoService = new CryptoService(this.storageService, this.secureStorageService, this.cryptoFunctionService); this.appIdService = new AppIdService(this.storageService); @@ -89,7 +93,8 @@ export class Main { this.containerService = new ContainerService(this.cryptoService); this.authService = new AuthService(this.cryptoService, this.apiService, this.userService, this.tokenService, this.appIdService, this.i18nService, this.platformUtilsService, this.messagingService, true); - this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService); + this.configurationService = new ConfigurationService(this.storageService, this.secureStorageService, + process.env.BITWARDENCLI_CONNECTOR_PLAINTEXT_SECRETS !== 'true'); this.syncService = new SyncService(this.configurationService, this.logService, this.cryptoFunctionService, this.apiService, this.messagingService, this.i18nService); this.program = new Program(this); diff --git a/src/services/configuration.service.ts b/src/services/configuration.service.ts index e92cfb6d..71937e9b 100644 --- a/src/services/configuration.service.ts +++ b/src/services/configuration.service.ts @@ -25,7 +25,8 @@ const Keys = { }; export class ConfigurationService { - constructor(private storageService: StorageService, private secureStorageService: StorageService) { } + constructor(private storageService: StorageService, private secureStorageService: StorageService, + private useSecureStorageForSecrets = true) { } async getDirectory(type: DirectoryType): Promise { const config = await this.storageService.get(Keys.directoryConfigPrefix + type); @@ -33,19 +34,21 @@ export class ConfigurationService { return config; } - switch (type) { - case DirectoryType.Ldap: - (config as any).password = await this.secureStorageService.get(Keys.ldap); - break; - case DirectoryType.AzureActiveDirectory: - (config as any).key = await this.secureStorageService.get(Keys.azure); - break; - case DirectoryType.Okta: - (config as any).token = await this.secureStorageService.get(Keys.okta); - break; - case DirectoryType.GSuite: - (config as any).privateKey = await this.secureStorageService.get(Keys.gsuite); - break; + if (this.useSecureStorageForSecrets) { + switch (type) { + case DirectoryType.Ldap: + (config as any).password = await this.secureStorageService.get(Keys.ldap); + break; + case DirectoryType.AzureActiveDirectory: + (config as any).key = await this.secureStorageService.get(Keys.azure); + break; + case DirectoryType.Okta: + (config as any).token = await this.secureStorageService.get(Keys.okta); + break; + case DirectoryType.GSuite: + (config as any).privateKey = await this.secureStorageService.get(Keys.gsuite); + break; + } } return config; } @@ -53,41 +56,43 @@ export class ConfigurationService { async saveDirectory(type: DirectoryType, config: LdapConfiguration | GSuiteConfiguration | AzureConfiguration | OktaConfiguration): Promise { const savedConfig: any = Object.assign({}, config); - switch (type) { - case DirectoryType.Ldap: - if (savedConfig.password == null) { - await this.secureStorageService.remove(Keys.ldap); - } else { - await this.secureStorageService.save(Keys.ldap, savedConfig.password); - savedConfig.password = StoredSecurely; - } - break; - case DirectoryType.AzureActiveDirectory: - if (savedConfig.key == null) { - await this.secureStorageService.remove(Keys.azure); - } else { - await this.secureStorageService.save(Keys.azure, savedConfig.key); - savedConfig.key = StoredSecurely; - } - break; - case DirectoryType.Okta: - if (savedConfig.token == null) { - await this.secureStorageService.remove(Keys.okta); - } else { - await this.secureStorageService.save(Keys.okta, savedConfig.token); - savedConfig.token = StoredSecurely; - } - break; - case DirectoryType.GSuite: - if (savedConfig.privateKey == null) { - await this.secureStorageService.remove(Keys.gsuite); - } else { - (config as GSuiteConfiguration).privateKey = savedConfig.privateKey = - savedConfig.privateKey.replace(/\\n/g, '\n'); - await this.secureStorageService.save(Keys.gsuite, savedConfig.privateKey); - savedConfig.privateKey = StoredSecurely; - } - break; + if (this.useSecureStorageForSecrets) { + switch (type) { + case DirectoryType.Ldap: + if (savedConfig.password == null) { + await this.secureStorageService.remove(Keys.ldap); + } else { + await this.secureStorageService.save(Keys.ldap, savedConfig.password); + savedConfig.password = StoredSecurely; + } + break; + case DirectoryType.AzureActiveDirectory: + if (savedConfig.key == null) { + await this.secureStorageService.remove(Keys.azure); + } else { + await this.secureStorageService.save(Keys.azure, savedConfig.key); + savedConfig.key = StoredSecurely; + } + break; + case DirectoryType.Okta: + if (savedConfig.token == null) { + await this.secureStorageService.remove(Keys.okta); + } else { + await this.secureStorageService.save(Keys.okta, savedConfig.token); + savedConfig.token = StoredSecurely; + } + break; + case DirectoryType.GSuite: + if (savedConfig.privateKey == null) { + await this.secureStorageService.remove(Keys.gsuite); + } else { + (config as GSuiteConfiguration).privateKey = savedConfig.privateKey = + savedConfig.privateKey.replace(/\\n/g, '\n'); + await this.secureStorageService.save(Keys.gsuite, savedConfig.privateKey); + savedConfig.privateKey = StoredSecurely; + } + break; + } } await this.storageService.save(Keys.directoryConfigPrefix + type, savedConfig); }