From bb7b8e1ad0e345862980a163b688f4554ebc1df8 Mon Sep 17 00:00:00 2001 From: Sakshis Date: Mon, 16 Dec 2024 13:09:06 +0000 Subject: [PATCH 1/4] removed missing-secure-java --- rules/java/security/missing-secure-java.yml | 70 ------------------- .../missing-secure-java-snapshot.yml | 32 --------- tests/java/missing-secure-java-test.yml | 15 ---- 3 files changed, 117 deletions(-) delete mode 100644 rules/java/security/missing-secure-java.yml delete mode 100644 tests/__snapshots__/missing-secure-java-snapshot.yml delete mode 100644 tests/java/missing-secure-java-test.yml diff --git a/rules/java/security/missing-secure-java.yml b/rules/java/security/missing-secure-java.yml deleted file mode 100644 index 755e6660..00000000 --- a/rules/java/security/missing-secure-java.yml +++ /dev/null @@ -1,70 +0,0 @@ -id: missing-secure-java -language: java -severity: warning -message: >- - Detected a cookie where the `Secure` flag is either missing or - disabled. The `Secure` cookie flag instructs the browser to forbid sending - the cookie over an insecure HTTP request. Set the `Secure` flag to `true` - so the cookie will only be sent over HTTPS. -note: >- - [CWE-614]: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute - [OWASP A05:2021]: Security Misconfiguration - [REFERENCES] - - https://owasp.org/Top10/A05_2021-Security_Misconfiguration -utils: - match_without_httponly: - kind: argument_list - has: - kind: object_creation_expression - inside: - stopBy: end - kind: method_invocation - - match_cookie_last: - kind: argument_list - has: - kind: method_invocation - has: - kind: argument_list - has: - kind: string_literal - - match_instance: - kind: local_variable_declaration - has: - stopBy: end - kind: identifier - follows: - stopBy: end - kind: variable_declarator - - match_identifier_with_simplecookie: - kind: identifier - inside: - stopBy: end - kind: local_variable_declaration - all: - - has: - stopBy: end - kind: type_identifier - regex: '^SimpleCookie$|^Cookie$' - - has: - stopBy: neighbor - kind: variable_declarator - all: - - has: - stopBy: neighbor - kind: identifier - - has: - stopBy: neighbor - kind: object_creation_expression - - not: - precedes: - stopBy: neighbor - kind: expression_statement -rule: - any: - - matches: match_instance - - matches: match_without_httponly - - matches: match_cookie_last - - matches: match_identifier_with_simplecookie diff --git a/tests/__snapshots__/missing-secure-java-snapshot.yml b/tests/__snapshots__/missing-secure-java-snapshot.yml deleted file mode 100644 index 3931463b..00000000 --- a/tests/__snapshots__/missing-secure-java-snapshot.yml +++ /dev/null @@ -1,32 +0,0 @@ -id: missing-secure-java -snapshots: - ? | - SimpleCookie s = new SimpleCookie("foo", "bar"); - .orElse( new NettyCookie( "foo", "bar" ) ); - Cookie z = new NettyCookie("foo", "bar"); - return HttpResponse.ok().cookie(Cookie.of("zzz", "ddd")); - : labels: - - source: s - style: primary - start: 13 - end: 14 - - source: SimpleCookie - style: secondary - start: 0 - end: 12 - - source: s - style: secondary - start: 13 - end: 14 - - source: new SimpleCookie("foo", "bar") - style: secondary - start: 17 - end: 47 - - source: s = new SimpleCookie("foo", "bar") - style: secondary - start: 13 - end: 47 - - source: SimpleCookie s = new SimpleCookie("foo", "bar"); - style: secondary - start: 0 - end: 48 diff --git a/tests/java/missing-secure-java-test.yml b/tests/java/missing-secure-java-test.yml deleted file mode 100644 index 507f951f..00000000 --- a/tests/java/missing-secure-java-test.yml +++ /dev/null @@ -1,15 +0,0 @@ -id: missing-secure-java -valid: - - | - Cookie c1 = getCookieSomewhere(); - return HttpResponse.ok().cookie(Cookie.of("foo", "bar").secure(true)); - Cookie cookie = request.getCookies().findCookie( "foobar" ) - Cookie c = new NettyCookie("foo", "bar"); - c.secure(true); - NettyCookie r = new NettyCookie("foo", "bar").secure(true); -invalid: - - | - SimpleCookie s = new SimpleCookie("foo", "bar"); - .orElse( new NettyCookie( "foo", "bar" ) ); - Cookie z = new NettyCookie("foo", "bar"); - return HttpResponse.ok().cookie(Cookie.of("zzz", "ddd")); From 2ba20581507e015bfb83edb47591627aa57d070d Mon Sep 17 00:00:00 2001 From: ESS ENN Date: Fri, 10 Jan 2025 20:14:13 +0530 Subject: [PATCH 2/4] sizeof-this-cpp --- rules/cpp/sizeof-this-cpp.yml | 44 +++++++++++++++++++ .../cbc-padding-oracle-java-snapshot.yml | 9 +++- .../sizeof-this-cpp-snapshot.yml | 2 + tests/cpp/size-of-this-test.yml | 7 +++ 4 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 rules/cpp/sizeof-this-cpp.yml create mode 100644 tests/__snapshots__/sizeof-this-cpp-snapshot.yml create mode 100644 tests/cpp/size-of-this-test.yml diff --git a/rules/cpp/sizeof-this-cpp.yml b/rules/cpp/sizeof-this-cpp.yml new file mode 100644 index 00000000..3044adf0 --- /dev/null +++ b/rules/cpp/sizeof-this-cpp.yml @@ -0,0 +1,44 @@ +id: sizeof-this-cpp +language: cpp +severity: warning +message: >- + Do not use `sizeof(this)` to get the number of bytes of the object in + memory. It returns the size of the pointer, not the size of the object. +note: >- + [CWE-467]: Use of sizeof() on a Pointer Type + [REFERENCES] + - https://wiki.sei.cmu.edu/confluence/display/c/ARR01-C.+Do+not+apply+the+sizeof+operator+to+a+pointer+when+taking+the+size+of+an+array +utils: + match_sizeof_this: + kind: sizeof_expression + has: + kind: parenthesized_expression + has: + kind: this + regex: "^this$" + inside: + stopBy: end + kind: return_statement + inside: + kind: compound_statement + follows: + kind: function_declarator + inside: + kind: function_definition + +rule: + kind: sizeof_expression + all: + - has: + stopBy: end + kind: this + - not: + has: + stopBy: end + any: + - nthChild: 2 + - kind: pointer_expression + - kind: ERROR + - kind: sizeof_expression + + diff --git a/tests/__snapshots__/cbc-padding-oracle-java-snapshot.yml b/tests/__snapshots__/cbc-padding-oracle-java-snapshot.yml index a3e9c11c..89c27d11 100644 --- a/tests/__snapshots__/cbc-padding-oracle-java-snapshot.yml +++ b/tests/__snapshots__/cbc-padding-oracle-java-snapshot.yml @@ -1,2 +1,9 @@ id: cbc-padding-oracle-java -snapshots: {} +snapshots: + ? | + Cipher.getInstance("AES/CBC/PKCS5Padding"); + : labels: + - source: Cipher.getInstance("AES/CBC/PKCS5Padding") + style: primary + start: 0 + end: 42 diff --git a/tests/__snapshots__/sizeof-this-cpp-snapshot.yml b/tests/__snapshots__/sizeof-this-cpp-snapshot.yml new file mode 100644 index 00000000..9875c137 --- /dev/null +++ b/tests/__snapshots__/sizeof-this-cpp-snapshot.yml @@ -0,0 +1,2 @@ +id: sizeof-this-cpp +snapshots: {} diff --git a/tests/cpp/size-of-this-test.yml b/tests/cpp/size-of-this-test.yml new file mode 100644 index 00000000..343b2a66 --- /dev/null +++ b/tests/cpp/size-of-this-test.yml @@ -0,0 +1,7 @@ +id: sizeof-this-cpp +valid: + - | + return sizeof(*this); +invalid: + - | + return sizeof(this); From 2b31bbdb06145a1bbdb54b1e82d344a3a0f56149 Mon Sep 17 00:00:00 2001 From: ESS ENN Date: Fri, 10 Jan 2025 20:19:53 +0530 Subject: [PATCH 3/4] tokio-postgres-empty-password-rust --- .../tokio-postgres-empty-password-rust.yml | 248 ++++++++++++++++++ ...-postgres-empty-password-rust-snapshot.yml | 54 ++++ ...okio-postgres-empty-password-rust-test.yml | 50 ++++ 3 files changed, 352 insertions(+) create mode 100644 rules/rust/security/tokio-postgres-empty-password-rust.yml create mode 100644 tests/__snapshots__/tokio-postgres-empty-password-rust-snapshot.yml create mode 100644 tests/rust/tokio-postgres-empty-password-rust-test.yml diff --git a/rules/rust/security/tokio-postgres-empty-password-rust.yml b/rules/rust/security/tokio-postgres-empty-password-rust.yml new file mode 100644 index 00000000..25c939bd --- /dev/null +++ b/rules/rust/security/tokio-postgres-empty-password-rust.yml @@ -0,0 +1,248 @@ +id: tokio-postgres-empty-password-rust +language: rust +severity: warning +message: >- + The application uses an empty credential. This can lead to unauthorized + access by either an internal or external malicious actor. It is + recommended to rotate the secret and retrieve them from a secure secret + vault or Hardware Security Module (HSM), alternatively environment + variables can be used if allowed by your company policy. +note: >- + [CWE-287] Improper Authentication. + [REFERENCES] + - https://docs.rs/tokio-postgres/latest/tokio_postgres/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + + +utils: + MATCH_FOLLOW_1: + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $CONFIG + - has: + kind: call_expression + regex: ^tokio_postgres::Config::new\(\)$ + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $CONFIG + - has: + kind: call_expression + regex: ^Config::new\(\)$ + any: + - follows: + stopBy: end + kind: use_declaration + has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config$ + - inside: + stopBy: end + follows: + stopBy: end + kind: use_declaration + has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config$ + + +rule: + kind: call_expression + not: + has: + stopBy: end + kind: ERROR + any: + # CONFIG IS DIRECT AND PWD IS DIRECT + - all: + - has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config::new()$ + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: string_literal + not: + has: + kind: string_content + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS DIRECT AND PWD IS INSTANCE + - all: + - has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config::new()$ + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: identifier + pattern: $PASSWORD + inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + has: + kind: identifier + pattern: $PASSWORD + precedes: + stopBy: end + kind: string_literal + not: + has: + kind: string_content + - kind: expression_statement + has: + kind: assignment_expression + has: + kind: identifier + pattern: $PASSWORD + precedes: + stopBy: end + kind: string_literal + not: + has: + kind: string_content + + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS INSTANCE AND PWD IS DIRECT + - all: + - has: + stopBy: end + kind: identifier + pattern: $CONFIG + any: + - inside: + stopBy: end + matches: MATCH_FOLLOW_1 + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: string_literal + not: + has: + kind: string_content + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS INSTANCE AND PWD IS INSTANCE + - all: + - has: + stopBy: end + kind: identifier + pattern: $CONFIG + any: + - inside: + stopBy: end + matches: MATCH_FOLLOW_1 + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: identifier + pattern: $PASSWORD + nthChild: 1 + inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $PASSWORD + - has: + kind: string_literal + not: + has: + kind: string_content + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $PASSWORD + - has: + kind: string_literal + not: + has: + kind: string_content + + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + diff --git a/tests/__snapshots__/tokio-postgres-empty-password-rust-snapshot.yml b/tests/__snapshots__/tokio-postgres-empty-password-rust-snapshot.yml new file mode 100644 index 00000000..199a0f9e --- /dev/null +++ b/tests/__snapshots__/tokio-postgres-empty-password-rust-snapshot.yml @@ -0,0 +1,54 @@ +id: tokio-postgres-empty-password-rust +snapshots: + ? |- + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } + : labels: + - source: |- + tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("") + style: primary + start: 79 + end: 184 + - source: tokio_postgres::Config::new + style: secondary + start: 79 + end: 106 + - source: |- + tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password + style: secondary + start: 79 + end: 180 + - source: '""' + style: secondary + start: 181 + end: 183 + - source: ("") + style: secondary + start: 180 + end: 184 diff --git a/tests/rust/tokio-postgres-empty-password-rust-test.yml b/tests/rust/tokio-postgres-empty-password-rust-test.yml new file mode 100644 index 00000000..2b85b2c4 --- /dev/null +++ b/tests/rust/tokio-postgres-empty-password-rust-test.yml @@ -0,0 +1,50 @@ +id: tokio-postgres-empty-password-rust +valid: + - | + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("postgres") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } + +invalid: + - | + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } \ No newline at end of file From 1cc31646d5697f6afa00deeece4662f12c56acf4 Mon Sep 17 00:00:00 2001 From: ESS ENN Date: Fri, 10 Jan 2025 20:22:49 +0530 Subject: [PATCH 4/4] tokio-postgres-hardcoded-password-rust --- ...tokio-postgres-hardcoded-password-rust.yml | 240 ++++++++++++++++++ ...tgres-hardcoded-password-rust-snapshot.yml | 58 +++++ ...-postgres-hardcoded-password-rust-test.yml | 50 ++++ 3 files changed, 348 insertions(+) create mode 100644 rules/rust/security/tokio-postgres-hardcoded-password-rust.yml create mode 100644 tests/__snapshots__/tokio-postgres-hardcoded-password-rust-snapshot.yml create mode 100644 tests/rust/tokio-postgres-hardcoded-password-rust-test.yml diff --git a/rules/rust/security/tokio-postgres-hardcoded-password-rust.yml b/rules/rust/security/tokio-postgres-hardcoded-password-rust.yml new file mode 100644 index 00000000..d7c8d491 --- /dev/null +++ b/rules/rust/security/tokio-postgres-hardcoded-password-rust.yml @@ -0,0 +1,240 @@ +id: tokio-postgres-hardcoded-password-rust +language: rust +severity: warning +message: >- + The application uses an empty credential. This can lead to unauthorized + access by either an internal or external malicious actor. It is + recommended to rotate the secret and retrieve them from a secure secret + vault or Hardware Security Module (HSM), alternatively environment + variables can be used if allowed by your company policy. +note: >- + [CWE-287] Improper Authentication. + [REFERENCES] + - https://docs.rs/tokio-postgres/latest/tokio_postgres/ + - https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures + +utils: + MATCH_FOLLOW_1: + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $CONFIG + - has: + kind: call_expression + regex: ^tokio_postgres::Config::new\(\)$ + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $CONFIG + - has: + kind: call_expression + regex: ^Config::new\(\)$ + any: + - follows: + stopBy: end + kind: use_declaration + has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config$ + - inside: + stopBy: end + follows: + stopBy: end + kind: use_declaration + has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config$ + + +rule: + kind: call_expression + not: + has: + stopBy: end + kind: ERROR + any: + # CONFIG IS DIRECT AND PWD IS DIRECT + - all: + - has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config::new()$ + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: string_literal + has: + kind: string_content + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS DIRECT AND PWD IS INSTANCE + - all: + - has: + stopBy: end + kind: scoped_identifier + regex: ^tokio_postgres::Config::new()$ + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: identifier + pattern: $PASSWORD + inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + has: + kind: identifier + pattern: $PASSWORD + precedes: + stopBy: end + kind: string_literal + has: + kind: string_content + - kind: expression_statement + has: + kind: assignment_expression + has: + kind: identifier + pattern: $PASSWORD + precedes: + stopBy: end + kind: string_literal + has: + kind: string_content + + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS INSTANCE AND PWD IS DIRECT + - all: + - has: + stopBy: end + kind: identifier + pattern: $CONFIG + any: + - inside: + stopBy: end + matches: MATCH_FOLLOW_1 + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: string_literal + has: + kind: string_content + nthChild: 1 + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression + # CONFIG IS INSTANCE AND PWD IS INSTANCE + - all: + - has: + stopBy: end + kind: identifier + pattern: $CONFIG + any: + - inside: + stopBy: end + matches: MATCH_FOLLOW_1 + - has: + kind: field_expression + regex: \.password$ + nthChild: 1 + - has: + kind: arguments + nthChild: 2 + has: + stopBy: end + kind: identifier + pattern: $PASSWORD + nthChild: 1 + inside: + stopBy: end + follows: + stopBy: end + any: + - kind: let_declaration + all: + - has: + kind: identifier + pattern: $PASSWORD + - has: + kind: string_literal + has: + kind: string_content + - kind: expression_statement + has: + kind: assignment_expression + all: + - has: + kind: identifier + pattern: $PASSWORD + - has: + kind: string_literal + has: + kind: string_content + + all: + - not: + has: + stopBy: end + nthChild: 2 + - not: + has: + stopBy: end + any: + - kind: block + - kind: array_expression diff --git a/tests/__snapshots__/tokio-postgres-hardcoded-password-rust-snapshot.yml b/tests/__snapshots__/tokio-postgres-hardcoded-password-rust-snapshot.yml new file mode 100644 index 00000000..211d2a32 --- /dev/null +++ b/tests/__snapshots__/tokio-postgres-hardcoded-password-rust-snapshot.yml @@ -0,0 +1,58 @@ +id: tokio-postgres-hardcoded-password-rust +snapshots: + ? |- + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("myPassword") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } + : labels: + - source: |- + tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("myPassword") + style: primary + start: 79 + end: 194 + - source: tokio_postgres::Config::new + style: secondary + start: 79 + end: 106 + - source: |- + tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password + style: secondary + start: 79 + end: 180 + - source: myPassword + style: secondary + start: 182 + end: 192 + - source: '"myPassword"' + style: secondary + start: 181 + end: 193 + - source: ("myPassword") + style: secondary + start: 180 + end: 194 diff --git a/tests/rust/tokio-postgres-hardcoded-password-rust-test.yml b/tests/rust/tokio-postgres-hardcoded-password-rust-test.yml new file mode 100644 index 00000000..895e52e4 --- /dev/null +++ b/tests/rust/tokio-postgres-hardcoded-password-rust-test.yml @@ -0,0 +1,50 @@ +id: tokio-postgres-hardcoded-password-rust +valid: + - | + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } + +invalid: + - | + async fn okTest2() -> Result<(), anyhow::Error> { + let (client, connection) = tokio_postgres::Config::new() + .host(shard_host_name.as_str()) + .user("postgres") + .password("myPassword") + .dbname("ninja") + .keepalives_idle(std::time::Duration::from_secs(30)) + .connect(NoTls) + .await + .map_err(|e| { + error!(log, "failed to connect to {}: {}", &shard_host_name, e); + Error::new(ErrorKind::Other, e) + })?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + tracing::error!("postgres db connection error: {}", e); + } + }); + + Ok(()) + } \ No newline at end of file