Skip to content

Commit 9055fbe

Browse files
1390 - SFTP Plugin Password Encryption (#258)
* first attempt * working encryption * finished * removed unnecesary import * testing updating magerc * hard-coding version * salt not found fix * salt not found fix 2 * forgot about types version
1 parent 8a98e00 commit 9055fbe

File tree

8 files changed

+66
-4
lines changed

8 files changed

+66
-4
lines changed

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ services:
3131
environment:
3232
MAGE_MONGO_URL: mongodb://mage-db:27017/magedb
3333
MAGE_TOKEN_EXPIRATION: "28800"
34+
# NOTE: default INSECURE salt value, recommend generate new UUID before deployment, **NOT** after deployment
35+
SFTP_PLUGIN_CONFIG_SALT: "A0E6D3B4-25BD-4DD6-BBC9-B367931966AB"
3436

3537
# Uncomment the following block to enable the TLS reverse proxy. You will
3638
# also need to generate the key and certificate as the README describes.

plugins/sftp/config/sftpConfig.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const eKey: Promise<CryptoKey> = window.crypto.subtle.generateKey(
2+
{
3+
name: "AES-GCM",
4+
length: 256, //can be 128, 192, or 256
5+
},
6+
true, //whether the key is extractable (i.e. can be used in exportKey)
7+
["encrypt", "decrypt"] //can "encrypt", "decrypt", "wrapKey", or "unwrapKey"
8+
)
9+
10+
export function arrayBufferToString(buffer: ArrayBuffer, encoding = 'utf-8'): string {
11+
const decoder = new TextDecoder(encoding);
12+
const view = new Uint8Array(buffer);
13+
return decoder.decode(view);
14+
}
15+
16+
export function stringToArrayBuffer(str: string): ArrayBuffer {
17+
let enc = new TextEncoder();
18+
var encoded = enc.encode(str);
19+
return encoded;
20+
}

plugins/sftp/service/package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/sftp/service/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"devDependencies": {
2727
"@types/archiver": "^6.0.2",
2828
"@types/bson": "^1.0.11",
29+
"@types/crypto-js": "4.1.1",
2930
"@types/express": "4.17.21",
3031
"@types/express-serve-static-core": "4.17.29",
3132
"@types/geojson": "^7946.0.7",
@@ -51,6 +52,7 @@
5152
},
5253
"dependencies": {
5354
"archiver": "^6.0.1",
55+
"crypto-js": "4.1.1",
5456
"ssh2-sftp-client": "^9.1.0"
5557
}
5658
}

plugins/sftp/service/src/configuration/SFTPPluginConfig.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { MageEventId } from '@ngageoint/mage.service/lib/entities/events/entities.events';
22
import { ArchiveFormat, CompletionAction, TriggerRule } from '../format/entities.format';
3+
import * as CryptoJS from 'crypto-js';
34

45
/**
56
* Contains various configuration values used by the plugin.
@@ -73,3 +74,19 @@ export const defaultSFTPPluginConfig = Object.freeze<SFTPPluginConfig>({
7374
password: ''
7475
}
7576
})
77+
78+
export async function encryptDecrypt(config: SFTPPluginConfig, isEncrypt: boolean): Promise<SFTPPluginConfig> {
79+
// NOTE: default INSECURE salt value, recommend generate new UUID before deployment, **NOT** after deployment
80+
const salt = "A0E6D3B4-25BD-4DD6-BBC9-B367931966AB"; // process.env.SFTP_PLUGIN_CONFIG_SALT;
81+
try {
82+
let tempConfig = config;
83+
if(salt === undefined) { throw new Error("No salt value found, update docker-compose value...") }
84+
const encryptedPass = isEncrypt ?
85+
CryptoJS.AES.encrypt(config.sftpClient.password, salt).toString() :
86+
CryptoJS.AES.decrypt(config.sftpClient.password, salt).toString();
87+
tempConfig.sftpClient.password = encryptedPass;
88+
return tempConfig;
89+
} catch (err) {
90+
throw err;
91+
}
92+
}

plugins/sftp/service/src/controller/controller.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Observation, ObservationAttrs, ObservationRepositoryForEvent } from '@n
44
import { PluginStateRepository } from '@ngageoint/mage.service/lib/plugins.api';
55
import SFTPClient from 'ssh2-sftp-client';
66
import { PassThrough } from 'stream';
7-
import { SFTPPluginConfig, defaultSFTPPluginConfig } from '../configuration/SFTPPluginConfig';
7+
import { SFTPPluginConfig, defaultSFTPPluginConfig, encryptDecrypt } from '../configuration/SFTPPluginConfig';
88
import { ArchiveFormat, ArchiveStatus, ArchiverFactory, ArchiveResult, TriggerRule } from '../format/entities.format';
99
import { SftpAttrs, SftpObservationRepository, SftpStatus } from '../adapters/adapters.sftp.mongoose';
1010

@@ -96,7 +96,7 @@ export class SftpController {
9696
*/
9797
public async getConfiguration(): Promise<SFTPPluginConfig> {
9898
if (this.configuration === null) {
99-
return await this.stateRepository.get().then(x => !!x ? x : this.stateRepository.put(defaultSFTPPluginConfig))
99+
return await this.stateRepository.get().then((x: SFTPPluginConfig | null) => !!x ? encryptDecrypt(x, false) : this.stateRepository.put(defaultSFTPPluginConfig))
100100
} else {
101101
return this.configuration
102102
}
@@ -107,7 +107,12 @@ export class SftpController {
107107
* @param configuration The new config to put into the state repo.
108108
*/
109109
public async updateConfiguration(configuration: SFTPPluginConfig) {
110-
await this.stateRepository.put(configuration)
110+
try {
111+
let config = await encryptDecrypt(configuration, true);
112+
await this.stateRepository.put(config)
113+
} catch (err) {
114+
this.console.log(`ERROR: updateConfiguration: ${err}`)
115+
}
111116
}
112117

113118
/**

plugins/sftp/service/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const sftpPluginHooks: InitPluginHook<typeof InjectedServices> = {
108108

109109
await controller.start()
110110

111-
res.status(200).json(configuration)
111+
res.status(200) //.json(configuration)
112112
})
113113

114114
return routes

service/src/environment/magerc.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ export MAGE_MONGO_CONN_RETRY_DELAY=5
6060
export MAGE_MONGO_TLS_INSECURE=false
6161
# Name of the db that contains the credentials
6262
export MAGE_MONGO_CRED_DB_NAME=
63+
export SFTP_PLUGIN_CONFIG_SALT="A0E6D3B4-25BD-4DD6-BBC9-B367931966AB"

0 commit comments

Comments
 (0)