Skip to content
This repository was archived by the owner on Feb 29, 2024. It is now read-only.

Commit 2887306

Browse files
committed
feat: add basic ssl for postgres
Signed-off-by: Kim Ebert <[email protected]>
1 parent c600cc7 commit 2887306

File tree

2 files changed

+61
-17
lines changed

2 files changed

+61
-17
lines changed

experimental/plugins/postgres_storage/Cargo.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ crate-type = ["staticlib","rlib","cdylib"]
1414

1515
[features]
1616
default = ["bn_openssl", "ed25519_sign_sodium", "ed25519_box_sodium", "sealedbox_sodium", "base58_rust_base58", "base64_rust_base64", "xsalsa20_sodium", "chacha20poly1305_ietf_sodium", "hash_openssl", "local_nodes_pool", "revocation_tests", "pwhash_argon2i13_sodium", "hmacsha256_sodium", "memzero_sodium", "randombytes_sodium"]
17-
bn_openssl = ["openssl", "int_traits"]
17+
bn_openssl = ["int_traits"]
1818
ed25519_sign_sodium = ["sodiumoxide"]
1919
ed25519_box_sodium = ["sodiumoxide"]
2020
sealedbox_sodium = ["sodiumoxide"]
@@ -23,7 +23,7 @@ base64_rust_base64 = ["base64"]
2323
xsalsa20_sodium = ["sodiumoxide"]
2424
chacha20poly1305_ietf_sodium = ["sodiumoxide"]
2525
pwhash_argon2i13_sodium = ["sodiumoxide"]
26-
hash_openssl = ["openssl"]
26+
hash_openssl = []
2727
local_nodes_pool = []
2828
revocation_tests = []
2929
sodium_static = []
@@ -46,7 +46,7 @@ hex = "0.2.0"
4646
libc = "0.2.60"
4747
log = "0.4.1"
4848
dirs = "1.0.4"
49-
openssl = { version = "=0.10.12", optional = true }
49+
openssl = { version = "=0.10.12" }
5050
owning_ref = "0.3.3"
5151
rand = "0.3"
5252
rust-base58 = {version = "0.0.4", optional = true}
@@ -65,7 +65,8 @@ named_type = "0.1.3"
6565
named_type_derive = "0.1.3"
6666
byteorder = "1.3.2"
6767
log-panics = "2.0.0"
68-
postgres = "0.15.2"
68+
postgres = { version = "0.15" }
69+
postgres-openssl = "0.1.0"
6970
r2d2 = "0.8.2"
7071
r2d2_postgres = "0.14.0"
7172
percent-encoding = "2.1.0"

experimental/plugins/postgres_storage/src/postgres_storage.rs

+56-13
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ extern crate owning_ref;
22
extern crate sodiumoxide;
33
extern crate r2d2;
44
extern crate r2d2_postgres;
5+
extern crate postgres_openssl;
56
extern crate percent_encoding;
67

78
use ::std::sync::RwLock;
89

910
use postgres;
1011
use self::r2d2_postgres::{TlsMode, PostgresConnectionManager};
12+
use self::postgres_openssl::{OpenSsl};
13+
use self::postgres_openssl::openssl::ssl::{SslMethod, SslConnector} ;
14+
use postgres_storage::postgres_openssl::openssl::ssl::SslConnectorBuilder;
15+
1116
use serde_json;
1217

1318
use self::owning_ref::OwningHandle;
@@ -369,10 +374,11 @@ impl StorageIterator for PostgresStorageIterator {
369374
}
370375
}
371376

372-
#[derive(Deserialize, Debug)]
377+
#[derive(Deserialize)]
373378
pub struct PostgresConfig {
374379
url: String,
375380
tls: Option<String>,
381+
tls_ca: Option<String>,
376382
// default off
377383
max_connections: Option<u32>,
378384
// default 5
@@ -384,28 +390,57 @@ pub struct PostgresConfig {
384390
// default 5
385391
wallet_scheme: Option<WalletScheme>, // default DatabasePerWallet
386392
database_name: Option<String>, // default _WALLET_DB
393+
394+
// For TLS
395+
#[serde(skip)]
396+
negotiator: Option<OpenSsl>,
397+
387398
}
388399

389400
impl PostgresConfig {
401+
402+
fn init_tls(&mut self) {
403+
debug!("initializing postgresql builder");
404+
405+
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
406+
407+
if self.tls_ca.is_some() {
408+
builder.set_ca_file(self.tls_ca.as_ref().unwrap());
409+
}
410+
411+
debug!("initializing postgresql negotiator");
412+
self.negotiator = Some(OpenSsl::from(builder.build()));
413+
}
414+
390415
fn tls(&self) -> postgres::TlsMode {
416+
debug!("tls");
391417
match &self.tls {
392418
Some(tls) => match tls.as_ref() {
393419
"None" => postgres::TlsMode::None,
394420
// TODO add tls support for connecting to postgres db
395-
//"Prefer" => postgres::TlsMode::Prefer(&postgres::Connection),
396-
//"Require" => postgres::TlsMode::Require(&postgres::Connection),
421+
"Prefer" => postgres::TlsMode::Prefer(self.negotiator.as_ref().unwrap()),
422+
"Require" => postgres::TlsMode::Require(self.negotiator.as_ref().unwrap()),
397423
_ => postgres::TlsMode::None
398424
},
399425
None => postgres::TlsMode::None
400426
}
401427
}
402428
fn r2d2_tls(&self) -> TlsMode {
429+
430+
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
431+
432+
if self.tls_ca.is_some() {
433+
builder.set_ca_file(self.tls_ca.as_ref().unwrap());
434+
}
435+
436+
let negotiator = OpenSsl::from(builder.build());
437+
403438
match &self.tls {
404439
Some(tls) => match tls.as_ref() {
405440
"None" => TlsMode::None,
406441
// TODO add tls support for connecting to postgres db
407-
//"Prefer" => TlsMode::Prefer(&postgres::Connection),
408-
//"Require" => TlsMode::Require(&postgres::Connection),
442+
"Prefer" => r2d2_postgres::TlsMode::Prefer(Box::new(negotiator)),
443+
"Require" => r2d2_postgres::TlsMode::Require(Box::new(negotiator)),
409444
_ => TlsMode::None
410445
},
411446
None => TlsMode::None
@@ -511,7 +546,7 @@ impl WalletStrategy for MultiWalletSingleTableStrategySharedPool {
511546
let url_base = PostgresStorageType::_admin_postgres_url(&config, &credentials);
512547
let url = PostgresStorageType::_postgres_url(_WALLETS_DB, &config, &credentials);
513548

514-
let conn = postgres::Connection::connect(&url_base[..], postgres::TlsMode::None)?;
549+
let conn = postgres::Connection::connect(&url_base[..], config.tls())?;
515550

516551
if let Err(error) = conn.execute(&_CREATE_WALLETS_DATABASE, &[]) {
517552
if error.code() != Some(&postgres::error::DUPLICATE_DATABASE) {
@@ -525,7 +560,7 @@ impl WalletStrategy for MultiWalletSingleTableStrategySharedPool {
525560
}
526561
conn.finish()?;
527562

528-
let conn = match postgres::Connection::connect(&url[..], postgres::TlsMode::None) {
563+
let conn = match postgres::Connection::connect(&url[..], config.tls()) {
529564
Ok(conn) => conn,
530565
Err(error) => {
531566
return Err(WalletStorageError::IOError(format!("Error occurred while connecting to wallet schema: {}", error)));
@@ -546,7 +581,7 @@ impl WalletStrategy for MultiWalletSingleTableStrategySharedPool {
546581
// insert metadata
547582
let url = PostgresStorageType::_postgres_url(_WALLETS_DB, &config, &credentials);
548583

549-
let conn = match postgres::Connection::connect(&url[..], postgres::TlsMode::None) {
584+
let conn = match postgres::Connection::connect(&url[..], config.tls()) {
550585
Ok(conn) => conn,
551586
Err(error) => {
552587
return Err(WalletStorageError::IOError(format!("Error occurred while connecting to wallet schema: {}", error)));
@@ -606,7 +641,7 @@ impl WalletStrategy for MultiWalletSingleTableStrategySharedPool {
606641
fn delete_wallet(&self, id: &str, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
607642
let url = PostgresStorageType::_postgres_url(&_WALLETS_DB, &config, &credentials);
608643

609-
let conn = match postgres::Connection::connect(&url[..], postgres::TlsMode::None) {
644+
let conn = match postgres::Connection::connect(&url[..], config.tls()) {
610645
Ok(conn) => conn,
611646
Err(error) => {
612647
return Err(WalletStorageError::IOError(format!("Error occurred while connecting to wallet schema: {}", error)));
@@ -1856,7 +1891,7 @@ impl WalletStorageType for PostgresStorageType {
18561891
.map_or(Ok(None), |v| v.map(Some))
18571892
.map_err(|err| CommonError::InvalidStructure(format!("Cannot deserialize credentials: {:?}", err)))?;
18581893

1859-
let config = match config {
1894+
let mut config = match config {
18601895
Some(config) => config,
18611896
None => return Err(WalletStorageError::ConfigError)
18621897
};
@@ -1865,6 +1900,8 @@ impl WalletStorageType for PostgresStorageType {
18651900
None => return Err(WalletStorageError::ConfigError)
18661901
};
18671902

1903+
config.init_tls();
1904+
18681905
match config.wallet_scheme {
18691906
Some(scheme) => match scheme {
18701907
WalletScheme::DatabasePerWallet => {
@@ -1938,7 +1975,7 @@ impl WalletStorageType for PostgresStorageType {
19381975
.map_or(Ok(None), |v| v.map(Some))
19391976
.map_err(|err| CommonError::InvalidStructure(format!("Cannot deserialize credentials: {:?}", err)))?;
19401977

1941-
let config = match config {
1978+
let mut config = match config {
19421979
Some(config) => config,
19431980
None => return Err(WalletStorageError::ConfigError)
19441981
};
@@ -1947,6 +1984,8 @@ impl WalletStorageType for PostgresStorageType {
19471984
None => return Err(WalletStorageError::ConfigError)
19481985
};
19491986

1987+
config.init_tls();
1988+
19501989
let strategy_read_lock = SELECTED_STRATEGY.read().unwrap();
19511990
strategy_read_lock.as_ref().delete_wallet(id, &config, &credentials)
19521991
}
@@ -1988,7 +2027,7 @@ impl WalletStorageType for PostgresStorageType {
19882027
.map_or(Ok(None), |v| v.map(Some))
19892028
.map_err(|err| CommonError::InvalidStructure(format!("Cannot deserialize credentials: {:?}", err)))?;
19902029

1991-
let config = match config {
2030+
let mut config = match config {
19922031
Some(config) => config,
19932032
None => return Err(WalletStorageError::ConfigError)
19942033
};
@@ -1997,6 +2036,8 @@ impl WalletStorageType for PostgresStorageType {
19972036
None => return Err(WalletStorageError::ConfigError)
19982037
};
19992038

2039+
config.init_tls();
2040+
20002041
// initialize using the global selected_strategy object
20012042
let r1 = SELECTED_STRATEGY.read().unwrap();
20022043
r1.as_ref().create_wallet(id, &config, &credentials, metadata)
@@ -2039,7 +2080,7 @@ impl WalletStorageType for PostgresStorageType {
20392080
.map_or(Ok(None), |v| v.map(Some))
20402081
.map_err(|err| CommonError::InvalidStructure(format!("Cannot deserialize credentials: {:?}", err)))?;
20412082

2042-
let config = match config
2083+
let mut config = match config
20432084
{
20442085
Some(config) => config,
20452086
None => return Err(WalletStorageError::ConfigError)
@@ -2049,6 +2090,8 @@ impl WalletStorageType for PostgresStorageType {
20492090
None => return Err(WalletStorageError::ConfigError)
20502091
};
20512092

2093+
config.init_tls();
2094+
20522095
// initialize using the global selected_strategy object
20532096
let r1 = SELECTED_STRATEGY.read().unwrap();
20542097
r1.as_ref().open_wallet(id, &config, &credentials)

0 commit comments

Comments
 (0)